NexusPi Git Node
lib/microReticulum/src/Transport.cpp efb87e1bd3a7ba19f45652b4f80a4ade1bb692a5 (efb87e1b) Text, 202.87 KB
Tff7b72#Tff7b72include T8b949e"Transport.h"
Tff7b72#Tff7b72include T8b949e"Link.h"
Tff7b72#Tff7b72include T8b949e"Reticulum.h"
Tff7b72#Tff7b72include T8b949e"Destination.h"
Tff7b72#Tff7b72include T8b949e"Identity.h"
Tff7b72#Tff7b72include T8b949e"Packet.h"
Tff7b72#Tff7b72include T8b949e"Interface.h"
Tff7b72#Tff7b72include T8b949e"Log.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Random.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/HKDF.h"
Tff7b72#Tff7b72include T8b949e"Utilities/OS.h"
Tff7b72#Tff7b72include T8b949e"Utilities/Persistence.h"
Tff7b72#Tff7b72include T8b949e<algorithm>
Tff7b72#Tff7b72include T8b949e<unistd.h>
Tff7b72#Tff7b72include T8b949e<time.h>
Tff7b72using Tff7b72namespace T7ee787RNSTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787TypeTff7b72:Tff7b72:T7ee787TransportTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787UtilitiesTb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
T8b949e///*static*/ std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> Transport::_interfaces;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3reference_wrapperTff7b72<Te6edf3InterfaceTff7b72>Tb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3lessTff7b72<Te6edf3InterfaceTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3reference_wrapperTff7b72<Te6edf3InterfaceTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3InterfaceTff7b72&Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinationsTb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinationsTb4b4b4;
Tff7b72#Tff7b72endif
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_pending_linksTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_active_linksTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packet_hashlistTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receiptsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3AnnounceEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3DestinationEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destination_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3ReverseEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_reverse_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3LinkEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_link_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3AnnounceEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_held_announcesTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3HAnnounceHandlerTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_handlersTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3TunnelEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tunnelsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3RateEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_rate_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_requestsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3PathRequestEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_discovery_path_requestsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_discovery_pr_tagsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_control_destinationsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_control_hashesTb4b4b4;
T8b949e///*static*/ std::set<Interface> Transport::_local_client_interfaces;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3reference_wrapperTff7b72<Tff7b72const Te6edf3InterfaceTff7b72>Tb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3lessTff7b72<Tff7b72const Te6edf3InterfaceTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_local_client_interfacesTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_pending_local_path_requestsTb4b4b4;
T8b949e// CBA
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3PacketEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packet_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_known_cached_packet_hashesTb4b4b4;
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_LOCAL_CLIENT_CACHE_MAXSIZE Tff7b72= T79c0ff512Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_start_time Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_job_interval Tff7b72= T79c0ff0.250Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_last_run Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_links_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_links_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receipts_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receipts_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announces_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announces_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tables_last_culled Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//float Transport::_tables_cull_interval = 5.0;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tables_cull_interval Tff7b72= T79c0ff60.0Tb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_saving_path_table Tff7b72= Tffa657falseTb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//uint16_t Transport::_hashlist_maxsize = 1000000;
T8b949e/*static*/ T8b949e//uint16_t Transport::_hashlist_maxsize = 100;
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_hashlist_maxsize Tff7b72= T79c0ff100Tb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//uint16_t Transport::_max_pr_tags = 32000;
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_max_pr_tags Tff7b72= T79c0ff32Tb4b4b4;
T8b949e// CBA
T8b949e// CBA ACCUMULATES
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_table_maxsize Tff7b72= T79c0ff100Tb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_table_maxpersist Tff7b72= T79c0ff100Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_saved Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_save_interval Tff7b72= T79c0ff3600.0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destination_table_crc Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Te6edf3Reticulum Td2a8ffTransport::_ownerTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE Whitelist 1: addresses of trusted local devices.
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3_boundary_local_addressesTb4b4b4;
T8b949e// FIREWALL MODE Whitelist 2: addresses mentioned by trusted local devices
T8b949e// or by already-allowed return traffic.
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3_boundary_mentioned_addressesTb4b4b4;
Tff7b72static Tff7b72const Tffa657uint16_t Te6edf3_boundary_maxsize Tff7b72= T79c0ff200Tb4b4b4;
T8b949e// FIREWALL MODE: Check if an interface is the backbone
Tff7b72static Tffa657bool Td2a8ffis_backbone_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3ifaceTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3ifaceTb4b4b4.Te6edf3is_backboneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72static Tffa657bool Td2a8ffis_boundary_trusted_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3ifaceTb4b4b4) Tb4b4b4{
T8b949e// In boundary mode, backbone interfaces are WAN/untrusted ingress.
T8b949e// All non-backbone ingress (LoRa, on-device/local interfaces) is local/trusted.
Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3ifaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72static Tffa657bool Td2a8ffis_boundary_untrusted_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3ifaceTb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72!Te6edf3is_boundary_trusted_interfaceTb4b4b4(Te6edf3ifaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72static Tffa657bool Td2a8ffis_boundary_address_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e/*static*/ Te6edf3Identity Td2a8ffTransport::_identityTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// CBA
T8b949e/*static*/ Te6edf3TransportTff7b72:Tff7b72:Te6edf3Callbacks Te6edf3TransportTff7b72:Tff7b72:Te6edf3_callbacksTb4b4b4;
T8b949e// CBA Stats
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packets_sent Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packets_received Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinations_added Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657size_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_memory Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657size_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_flash Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657void Td2a8ffTransport::startTb4b4b4(Tff7b72const Te6edf3ReticulumTff7b72& Te6edf3reticulum_instanceTb4b4b4) Tb4b4b4{
Te6edf3INFOTb4b4b4(Ta5d6ff"Ta5d6ffTransport starting...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657trueTb4b4b4;
Te6edf3_owner Tff7b72= Te6edf3reticulum_instanceTb4b4b4;
T8b949e// Initialize time-based variables *after* time offset update
Te6edf3_jobs_last_run Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_links_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_receipts_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_announces_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_tables_last_culled Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_last_saved Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// ensure required directories exist
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3OSTff7b72:Tff7b72:Te6edf3directory_existsTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffNo cache directory, creating...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3create_directoryTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Tffa657char Te6edf3transport_identity_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3transport_identity_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/transport_identityTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffChecking for transport identity...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_identity Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3from_fileTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffNo valid Transport Identity in storage, creating...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_identity Tff7b72= Te6edf3IdentityTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_identityTb4b4b4.Te6edf3to_fileTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffLoaded Transport Identity from storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffFailed to check for transport identity, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// TODO
T8b949e/*
packet_hashlist_path = Reticulum::storagepath + "/packet_hashlist";
if (!owner.is_connected_to_shared_instance()) {
if (os.path.isfile(packet_hashlist_path)) {
try {
//p file = open(packet_hashlist_path, "rb")
//p Transport.packet_hashlist = umsgpack.unpackb(file.read())
//p file.close()
}
catch (std::exception& e) {
ERRORF("Could not load packet hashlist from storage, the contained exception was: %s", e.what());
}
}
}
*/
T8b949e// Create transport-specific destination for path request
Te6edf3Destination Te6edf3path_request_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpath.requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_destinationTb4b4b4.Te6edf3set_packet_callbackTb4b4b4(Te6edf3path_request_handlerTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3path_request_destinationTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3path_request_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCreated transport-specific path request destination Ta5d6ff" Tff7b72+ Te6edf3path_request_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Create transport-specific destination for tunnel synthesize
Te6edf3Destination Te6edf3tunnel_synthesize_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6fftunnel.synthesizeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3set_packet_callbackTb4b4b4(Te6edf3tunnel_synthesize_handlerTb4b4b4)Tb4b4b4;
T8b949e// CBA BUG?
T8b949e//p Transport.control_destinations.append(Transport.tunnel_synthesize_handler)
T8b949e// CBA ACCUMULATES
Te6edf3_control_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3tunnel_synthesize_destinationTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCreated transport-specific tunnel synthesize destination Ta5d6ff" Tff7b72+ Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e// CBA Threading
T8b949e//p thread = threading.Thread(target=Transport.jobloop, daemon=True)
T8b949e//p thread.start()
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3INFOTb4b4b4(Ta5d6ff"Ta5d6ffTransport mode is enabledTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Read in path table and then write and clean in case any entries are invalid
Te6edf3read_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffWriting path table and cleaning caches to clean-up any orphaned paths/filesTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3write_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3clean_cachesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3read_tunnel_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Create transport-specific destination for probe requests
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3probe_destination_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3Destination Te6edf3probe_destinationTb4b4b4(Te6edf3_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffprobeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3accepts_linksTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3set_proof_strategyTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_ALLTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCreated probe responder destination Ta5d6ff" Tff7b72+ Te6edf3probe_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffTransport Instance will respond to probe requests on Ta5d6ff" Tff7b72+ Te6edf3probe_destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffTransport instance Ta5d6ff" Tff7b72+ Te6edf3_identityTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff startedTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_start_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// TODO
T8b949e/*p
// Synthesize tunnels for any interfaces wanting it
for interface in Transport.interfaces:
interface.tunnel_id = None
if hasattr(interface, "wants_tunnel") and interface.wants_tunnel:
Transport.synthesize_tunnel(interface)
*/
T8b949e//#ifndef NDEBUG
T8b949e// CBA DEBUG
Te6edf3dump_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//#endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_jobs_last_run Tff7b72+ Te6edf3_job_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3jobsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_last_run Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::jobsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e//TRACE("Transport::jobs()");
T8b949e// Heap telemetry: snapshot at jobs entry
Tffa657size_t Te6edf3_jobs_heap_entry Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3PacketTff7b72> Te6edf3outgoingTb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3path_requestsTb4b4b4;
Tffa657int Te6edf3countTb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657trueTb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_jobs_lockedTb4b4b4) Tb4b4b4{
T8b949e// Process active and pending link lists
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_links_last_checked Tff7b72+ Te6edf3_links_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3pending_linksTb4b4b4(Te6edf3_pending_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3pending_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
T8b949e// If we are not a Transport Instance, finding a pending link
T8b949e// that was never activated will trigger an expiry of the path
T8b949e// to the destination, and an attempt to rediscover the path.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3expire_pathTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// If we are connected to a shared instance, it will take
T8b949e// care of sending out a new path request. If not, we will
T8b949e// send one directly.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657double Te6edf3last_path_request Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3last_path_request Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_path_requestTb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_MITb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never establishedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//if (path_requests.find(link.destination().hash()) == path_requests.end()) {
Tff7b72if Tb4b4b4(Te6edf3path_requestsTb4b4b4.Te6edf3countTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3_pending_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
Te6edf3_active_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3_links_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Process receipts list for timed-out packets
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_receipts_last_checked Tff7b72+ Te6edf3_receipts_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Te6edf3_receiptsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3MAX_RECEIPTSTb4b4b4) Tb4b4b4{
T8b949e//p culled_receipt = Transport.receipts.pop(0)
Te6edf3PacketReceipt Te6edf3culled_receipt Tff7b72= Te6edf3_receiptsTb4b4b4.Te6edf3frontTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_receiptsTb4b4b4.Te6edf3pop_frontTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3culled_receiptTb4b4b4.Te6edf3set_timeoutTb4b4b4(T79c0ff-1Tb4b4b4)Tb4b4b4;
Te6edf3culled_receiptTb4b4b4.Te6edf3check_timeoutTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3cull_receiptsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3receiptTb4b4b4.Te6edf3check_timeoutTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3receiptTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3SENTTb4b4b4) Tb4b4b4{
T8b949e//p if receipt in Transport.receipts:
T8b949e//p Transport.receipts.remove(receipt)
Te6edf3cull_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA since modifying of collection while iterating is forbidden
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_receipts_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Process announces needing retransmission
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_announces_last_checked Tff7b72+ Te6edf3_announces_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-TBL size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72while Tb4b4b4(Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Culling queued announce to protect heap (annc=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_announce_tableTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e//p for destination_hash in Transport.announce_table:
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3announce_entryTb4b4b4] Tff7b72: Te6edf3_announce_tableTb4b4b4) Tb4b4b4{
T8b949e//for (auto& pair : _announce_table) {
T8b949e// const auto& destination_hash = pair.first;
T8b949e// auto& announce_entry = pair.second;
T8b949e//TRACE("[0] announce entry data size: " + std::to_string(announce_entry._packet.data().size()));
T8b949e//p announce_entry = Transport.announce_table[destination_hash]
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-ENTRY dest=Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff retries=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retriesTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff block=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timeout_in=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeout Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3LOCAL_REBROADCASTS_MAXTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCompleted announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, local rebroadcast limit reachedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA OK to modify collection here since we're immediately exiting iteration
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-CULL dest=Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff retries=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retriesTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff reason=retry_limitTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCompleted announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, retry limit reachedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA OK to modify collection here since we're immediately exiting iteration
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeoutTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffPerforming announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeout Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_G Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RWTb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
T8b949e//p packet = announce_entry[5]
T8b949e//p block_rebroadcasts = announce_entry[7]
T8b949e//p attached_interface = announce_entry[8]
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3context_types Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tb4b4b4{
Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4;
Tb4b4b4}
T8b949e//p announce_data = packet.data
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
T8b949e//announce_destination.hash(announce_entry._packet.destination_hash());
Te6edf3Destination Te6edf3announce_destinationTb4b4b4(Te6edf3announce_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//P announce_destination.hexhash = announce_destination.hash.hex()
T8b949e//if (announce_entry._attached_interface) {
T8b949e//TRACE("[1] interface is valid");
T8b949e//TRACE("[1] interface: " + announce_entry._attached_interface.debugString());
T8b949e//TRACE("[1] interface: " + announce_entry._attached_interface.toString());
T8b949e//}
Te6edf3Packet Te6edf3new_packetTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
T8b949e//{Type::NONE},
Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interfaceTb4b4b4,
T8b949e//{Type::NONE},
Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3announce_contextTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3TransportTff7b72:Tff7b72:Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_hopsTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasting announce as path response for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with hop count Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: SENDING PATH-RESP announce for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff attached=Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interface Tff7b72? Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ffNONETa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasting announce for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with hop count Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3outgoingTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3new_packetTb4b4b4)Tb4b4b4;
T8b949e// This handles an edge case where a peer sends a past
T8b949e// request for a destination just after an announce for
T8b949e// said destination has arrived, but before it has been
T8b949e// rebroadcast locally. In such a case the actual announce
T8b949e// is temporarily held, and then reinserted when the path
T8b949e// request has been served to the peer.
T8b949e//p if destination_hash in Transport.held_announces:
Tff7b72auto Te6edf3iter Tff7b72=Te6edf3_held_announcesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//p held_entry = Transport.held_announces.pop(destination_hash)
Tff7b72auto Te6edf3held_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
T8b949e//p Transport.announce_table[destination_hash] = held_entry
T8b949e//_announce_table[destination_hash] = held_entry;
T8b949e//_announce_table.insert_or_assign({destination_hash, held_entry});
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Te6edf3held_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReinserting held announce into tableTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA Must break after erase to avoid iterator invalidation
T8b949e// (same pattern as the other two erases above in this loop)
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3_announces_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Cull held announces that are older than 60 seconds or if map exceeds cap
Tb4b4b4{
Tff7b72const Tffa657double Te6edf3held_timeout Tff7b72= T79c0ff60.0Tb4b4b4;
Tff7b72const Tffa657uint16_t Te6edf3held_maxsize Tff7b72= T79c0ff32Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3held_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCulling expired held announce for Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3iter Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72+Tff7b72+Te6edf3iterTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72while Tb4b4b4(Te6edf3_held_announcesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3held_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCulling oldest held announce (cap Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3held_maxsizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_held_announcesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the packet hashlist if it has reached its max size
Tff7b72while Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_hashlist_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3_packet_hashlistTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Cull the boundary mentioned addresses if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_boundary_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72>Tff7b72:Tff7b72:Te6edf3iterator Te6edf3iter Tff7b72= Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3advanceTb4b4b4(Te6edf3iterTb4b4b4, Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_boundary_maxsizeTb4b4b4)Tb4b4b4;
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Cull the boundary local addresses if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_boundary_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72>Tff7b72:Tff7b72:Te6edf3iterator Te6edf3iter Tff7b72= Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3advanceTb4b4b4(Te6edf3iterTb4b4b4, Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_boundary_maxsizeTb4b4b4)Tb4b4b4;
Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Cull the path request tags list if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_max_pr_tagsTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72>Tff7b72:Tff7b72:Te6edf3iterator Te6edf3iter Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3advanceTb4b4b4(Te6edf3iterTb4b4b4, Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_max_pr_tagsTb4b4b4)Tb4b4b4;
Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_tables_last_culled Tff7b72+ Te6edf3_tables_cull_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA Disabled following since we're calling immediately after adding to path table now
T8b949e// Cull the path table if it has reached its max size
T8b949e//cull_path_table();
T8b949e// Cull the reverse table according to timeout
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_reverse_entriesTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3packet_hashTb4b4b4, Te6edf3reverse_entryTb4b4b4] Tff7b72: Te6edf3_reverse_tableTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3REVERSE_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_reverse_entriesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the link table according to timeout
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_linksTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3link_idTb4b4b4, Te6edf3link_entryTb4b4b4] Tff7b72: Te6edf3_link_tableTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_validatedTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3LINK_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_linksTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3link_entryTb4b4b4.Te6edf3_proof_timeoutTb4b4b4) Tb4b4b4{
Te6edf3stale_linksTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3last_path_request Tff7b72= T79c0ff0.0Tb4b4b4;
Tff7b72const Tff7b72autoTff7b72& Te6edf3iter Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3last_path_request Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3lr_taken_hops Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Tffa657bool Te6edf3path_request_throttle Tff7b72= Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_path_requestTb4b4b4) Tff7b72< Te6edf3PATH_REQUEST_MITb4b4b4;
Tffa657bool Te6edf3path_request_conditions Tff7b72= Tffa657falseTb4b4b4;
T8b949e// If the path has been invalidated between the time of
T8b949e// making the link request and now, try to rediscover it
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3has_pathTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and path is now missingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If this link request was originated from a local client
T8b949e// attempt to rediscover a path to the destination, if this
T8b949e// has not already happened recently.
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3path_request_throttle Tff7b72&Tff7b72& Te6edf3lr_taken_hops Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted local client link was never establishedTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If the link destination was previously only 1 hop
T8b949e// away, this likely means that it was local to one
T8b949e// of our interfaces, and that it roamed somewhere else.
T8b949e// In that case, try to discover a new path.
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3path_request_throttle Tff7b72&Tff7b72& Te6edf3hops_toTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and destination was previously local to an interface on this instanceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If the link destination was previously only 1 hop
T8b949e// away, this likely means that it was local to one
T8b949e// of our interfaces, and that it roamed somewhere else.
T8b949e// In that case, try to discover a new path.
Tff7b72else Tff7b72if Tb4b4b4( Tff7b72!Te6edf3path_request_throttle Tff7b72and Te6edf3lr_taken_hops Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and link initiator is local to an interface on this instanceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3path_request_conditionsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3path_requestsTb4b4b4.Te6edf3countTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Drop current path if we are not a transport instance, to
T8b949e// allow using higher-hop count paths or reused announces
T8b949e// from newly adjacent transport instances.
Te6edf3expire_pathTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the path table
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_pathsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3attached_interface Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3destination_expiryTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attached_interface Tff7b72&Tff7b72& Te6edf3attached_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4) Tb4b4b4{
Te6edf3destination_expiry Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3AP_PATH_TIMETb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3attached_interface Tff7b72&Tff7b72& Te6edf3attached_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3destination_expiry Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3ROAMING_PATH_TIMETb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3destination_expiry Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3DESTINATION_TIMEOUTTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3destination_expiryTb4b4b4) Tb4b4b4{
Te6edf3stale_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3attached_interfaceTb4b4b4) Tb4b4b4{
Te6edf3stale_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff was removed since the attached interface is missingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_interfacesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3attached_interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3stale_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff was removed since the attached interface no longer existsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the pending discovery path requests table
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_discovery_path_requestsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3path_entryTb4b4b4] Tff7b72: Te6edf3_discovery_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3path_entryTb4b4b4.Te6edf3_timeoutTb4b4b4) Tb4b4b4{
Te6edf3stale_discovery_path_requestsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffWaiting path request for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the path requests table (entries older than destination timeout)
Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_path_requestsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3timestampTb4b4b4] Tff7b72: Te6edf3_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3timestamp Tff7b72+ Te6edf3DESTINATION_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_path_requestsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_path_requestsTb4b4b4) Tb4b4b4{
Te6edf3_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull pending local path requests for interfaces that no longer exist
Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_plprTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3iface_hashTb4b4b4] Tff7b72: Te6edf3_pending_local_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3iface_hash Tff7b72|Tff7b72| Te6edf3_interfacesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3iface_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3stale_plprTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_plprTb4b4b4) Tb4b4b4{
Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the tunnel table
Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_tunnelsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3tunnel_idTb4b4b4, Te6edf3tunnel_entryTb4b4b4] Tff7b72: Te6edf3_tunnelsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3tunnel_entryTb4b4b4.Te6edf3_expiresTb4b4b4) Tb4b4b4{
Te6edf3stale_tunnelsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3tunnel_idTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTunnel Ta5d6ff" Tff7b72+ Te6edf3tunnel_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_tunnel_pathsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3tunnel_entryTb4b4b4.Te6edf3_serialised_pathsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3DESTINATION_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_tunnel_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTunnel path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//for (const auto& destination_hash : stale_tunnel_paths) {
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_tunnel_pathsTb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3TunnelEntryTff7b72&Tff7b72>Tb4b4b4(Te6edf3tunnel_entryTb4b4b4)Tb4b4b4.Te6edf3_serialised_pathsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3countTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff tunnel pathsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3remove_reverse_entriesTb4b4b4(Te6edf3stale_reverse_entriesTb4b4b4)Tb4b4b4;
Te6edf3remove_linksTb4b4b4(Te6edf3stale_linksTb4b4b4)Tb4b4b4;
Te6edf3remove_pathsTb4b4b4(Te6edf3stale_pathsTb4b4b4)Tb4b4b4;
Te6edf3remove_discovery_path_requestsTb4b4b4(Te6edf3stale_discovery_path_requestsTb4b4b4)Tb4b4b4;
Te6edf3remove_tunnelsTb4b4b4(Te6edf3stale_tunnelsTb4b4b4)Tb4b4b4;
T8b949e//#ifndef NDEBUG
Te6edf3dump_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//#endif
Te6edf3_tables_last_culled Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA Periodically persist data
T8b949e//if (OS::time() > (_last_saved + _save_interval)) {
T8b949e// persist_data();
T8b949e// _last_saved = OS::time();
T8b949e//}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Transport jobs were locked, do nothing
T8b949e//p pass
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAn exception occurred while running Transport jobs.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e// Heap telemetry: snapshot at jobs exit
Tb4b4b4{
Tffa657size_t Te6edf3_jobs_heap_exit Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3_jobs_delta Tff7b72= Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_jobs_heap_exit Tff7b72- Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_jobs_heap_entryTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_jobs_delta Tff7b72< T79c0ff-64 Tff7b72|Tff7b72| Te6edf3_jobs_delta Tff7b72> T79c0ff64Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[HEAP-TEL] jobs: %d bytes (heap=%u)Ta5d6ff"Tb4b4b4, Te6edf3_jobs_deltaTb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3_jobs_heap_exitTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA send announce retransmission packets
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3packet Tff7b72: Te6edf3outgoingTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: OUTGOING announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff attached=Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4) Tff7b72? Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ffNONETa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA send link-related path requests
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3path_requestsTb4b4b4) Tb4b4b4{
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::transmitTb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3rawTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::transmit()Ta5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_transmit_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_callbacksTb4b4b4.Te6edf3_transmit_packetTb4b4b4(Te6edf3rawTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing transmit packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72try Tb4b4b4{
T8b949e//if hasattr(interface, "ifac_identity") and interface.ifac_identity != None:
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Calculate packet access code by signing the raw packet
T8b949e// and taking the last ifac_size bytes of the signature
Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3ifac_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3signTb4b4b4(Te6edf3rawTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3ifac Tff7b72= Te6edf3signatureTb4b4b4.Te6edf3rightTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Generate mask via HKDF
Te6edf3Bytes Te6edf3mask Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3ifacTb4b4b4,
Te6edf3interfaceTb4b4b4.Te6edf3ifac_keyTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// Set IFAC flag in header byte 0
Tffa657uint8_t Te6edf3new_header0 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72| T79c0ff0x80Tb4b4b4;
Tffa657uint8_t Te6edf3new_header1 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
T8b949e// Assemble new payload: new_header + ifac + raw[2:]
Te6edf3Bytes Te6edf3new_rawTb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header0Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header1Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3ifacTb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Mask payload
Te6edf3Bytes Te6edf3masked_rawTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Mask first header byte, keep IFAC flag set
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Tb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4) Tff7b72| T79c0ff0x80Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3i Tff7b72=Tff7b72= T79c0ff1 Tff7b72|Tff7b72| Te6edf3i Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Mask second header byte and payload
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Don't mask the IFAC itself
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Send it
Te6edf3interfaceTb4b4b4.Te6edf3send_outgoingTb4b4b4(Te6edf3masked_rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3interfaceTb4b4b4.Te6edf3send_outgoingTb4b4b4(Te6edf3rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while transmitting on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Td2a8ffTransport::outboundTb4b4b4(Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3_packets_sentTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//throw std::invalid_argument("Can not send packet with no destination.");
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffCan not send packet with no destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: destination=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_jobs_runningTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: sleeping...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(T79c0ff0.0005Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657trueTb4b4b4;
Tffa657bool Te6edf3sent Tff7b72= Tffa657falseTb4b4b4;
Tffa657double Te6edf3outbound_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Check if we have a known path for the destination in the path table
T8b949e//if packet.packet_type != RNS.Packet.ANNOUNCE and packet.destination.type != RNS.Destination.PLAIN and packet.destination.type != RNS.Destination.GROUP and packet.destination_hash in Transport.destination_table:
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3GROUP Tff7b72&Tff7b72& Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Path to destination is knownTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//outbound_interface = Transport.destination_table[packet.destination_hash][5]
Te6edf3DestinationEntryTff7b72& Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// If there's more than one hop to the destination, and we know
T8b949e// a path, we insert the packet into transport by adding the next
T8b949e// transport nodes address to the header, and modifying the flags.
T8b949e// This rule applies both for "normal" transport, and when connected
T8b949e// to a local shared Reticulum instance.
T8b949e//if Transport.destination_table[packet.destination_hash][2] > 1:
Tff7b72if Tb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffForwarding packet to next closest interface...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tb4b4b4{
T8b949e// Insert packet into transport
T8b949e//new_flags = (RNS.Packet.HEADER_2) << 6 | (Transport.TRANSPORT) << 4 | (packet.flags & 0b00001111)
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = struct.pack("!B", new_flags)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
T8b949e//new_raw += packet.raw[1:2]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff1Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += Transport.destination_table[packet.destination_hash][1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
T8b949e//_destination_table[packet.destination_hash][0] = time.time()
Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// In the special case where we are connected to a local shared
T8b949e// Reticulum instance, and the destination is one hop away, we
T8b949e// also add transport headers to inject the packet into transport
T8b949e// via the shared instance. Normally a packet for a destination
T8b949e// one hop away would just be broadcast directly, but since we
T8b949e// are "behind" a shared instance, we need to get that instance
T8b949e// to transport it onto the network.
T8b949e//elif Transport.destination_table[packet.destination_hash][2] == 1 and Transport.owner.is_connected_to_shared_instance:
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_hops Tff7b72=Tff7b72= T79c0ff1 Tff7b72&Tff7b72& Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet for directly connected interface to shared instance...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tb4b4b4{
T8b949e// Insert packet into transport
T8b949e//new_flags = (RNS.Packet.HEADER_2) << 6 | (Transport.TRANSPORT) << 4 | (packet.flags & 0b00001111)
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = struct.pack("!B", new_flags)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
T8b949e//new_raw += packet.raw[1:2]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += Transport.destination_table[packet.destination_hash][1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
T8b949e//Transport.destination_table[packet.destination_hash][0] = time.time()
Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// If none of the above applies, we know the destination is
T8b949e// directly reachable, and also on which interface, so we
T8b949e// simply transmit the packet directly on that one.
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet over directly connected interface...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// If we don't have a known path for the destination, we'll
T8b949e// broadcast the packet on all outgoing interfaces, or the
T8b949e// just the relevant interface if the packet has an attached
T8b949e// interface, or belongs to a link.
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Path to destination is unknownTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3stored_hash Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Checking interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3OUTTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3should_transmit Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3destination_linkTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3invalid_argumentTb4b4b4(Ta5d6ff"Ta5d6ffPacket is not associated with a LinkTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_linkTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Pscket destination is link-closed, not transmittingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// CBA Bug? Destination has no member attached_interface
T8b949e//z if (interface != packet.destination().attached_interface()) {
T8b949e//z should_transmit = false;
T8b949e//z }
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3interface Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet has wrong attached interface, not transmittingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet has no attached interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to AP modeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
T8b949e//Destination local_destination({Type::NONE});
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
T8b949e//if (local_destination) {
Tff7b72if Tb4b4b4(Te6edf3found_localTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//if (iter != _destinations.end()) {
T8b949e// local_destination = (*iter).second;
T8b949e//}
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAllowing announce broadcast on roaming-mode interface from instance-local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3from_interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//if from_interface == None or not hasattr(from_interface, "mode"):
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interface Tff7b72|Tff7b72| Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface doesn't existTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface has no mode configuredTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to roaming-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to boundary-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4) Tb4b4b4{
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
T8b949e// next and filter pattern?
T8b949e// next(iterable, default)
T8b949e// list comprehension: [x for x in xyz if x in a]
T8b949e// CBA TODO confirm that above pattern just selects the first matching destination
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e//Destination local_destination({Type::Destination::NONE});
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
T8b949e//if (local_destination) {
Tff7b72if Tb4b4b4(Te6edf3found_localTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAllowing announce broadcast on boundary-mode interface from instance-local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3from_interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interface Tff7b72|Tff7b72| Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface doesn't existTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface has no mode configuredTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to roaming-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Currently, annouces originating locally are always
T8b949e// allowed, and do not conform to bandwidth caps.
T8b949e// TODO: Rethink whether this is actually optimal.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
if not hasattr(interface, "announce_cap"):
interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP
if not hasattr(interface, "announce_allowed_at"):
interface.announce_allowed_at = 0
if not hasattr(interface, "announce_queue"):
interface.announce_queue = []
*/
Tffa657bool Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queued_announces Tff7b72&Tff7b72& Te6edf3outbound_time Tff7b72> Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3wait_time Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3tx_time Tff7b72= Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff8Tb4b4b4) Tff7b72/ Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wait_time Tff7b72= Tb4b4b4(Te6edf3tx_time Tff7b72/ Te6edf3interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3outbound_time Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3outbound_time Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72< Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MAX_QUEUED_ANNOUNCESTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3should_queue Tff7b72= Tffa657trueTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3_destination Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint64_t Te6edf3emission_timestamp Tff7b72= Te6edf3announce_emittedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3should_queue Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3emission_timestamp Tff7b72> Te6edf3entryTb4b4b4.Te6edf3_emittedTb4b4b4) Tb4b4b4{
Te6edf3entryTb4b4b4.Te6edf3_time Tff7b72= Te6edf3outbound_timeTb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_hops Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_emitted Tff7b72= Te6edf3emission_timestampTb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_raw Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3should_queueTb4b4b4) Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3AnnounceEntry Te6edf3entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_timeTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3announce_emittedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4.Te6edf3add_announceTb4b4b4(Te6edf3entryTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
T8b949e// CBA ACCUMULATES
Te6edf3interfaceTb4b4b4.Te6edf3add_announceTb4b4b4(Te6edf3entryTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queued_announcesTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3wait_time Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657doubleTb4b4b4)T79c0ff0Tb4b4b4)Tb4b4b4;
T8b949e// CBA TODO THREAD?
T8b949e//z timer = threading.Timer(wait_time, interface.process_announce_queue)
T8b949e//z timer.start()
Tff7b72if Tb4b4b4(Te6edf3wait_time Tff7b72< T79c0ff1000Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Te6edf3wait_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3wait_timeTff7b72/T79c0ff1000Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tffa657double Te6edf3wait_time Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657doubleTb4b4b4)T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3wait_time Tff7b72< T79c0ff1000Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Te6edf3wait_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3wait_timeTff7b72/T79c0ff1000Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//p pass
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//p pass
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3should_transmitTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet transmission allowedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: TX-OUT announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3stored_hashTb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_packet_hashlistTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_hashlist_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3_packet_hashlistTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stored_hash Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// TODO: Re-evaluate potential for blocking
T8b949e// def send_packet():
T8b949e// Transport.transmit(interface, packet.raw)
T8b949e// thread = threading.Thread(target=send_packet)
T8b949e// thread.daemon = True
T8b949e// thread.start()
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet transmission refusedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: TX-REFUSED announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff refused on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3sentTb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3sentTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3sent_atTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Don't generate receipt if it has been explicitly disabled
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3create_receiptTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72&
T8b949e// Only generate receipts for DATA packets
Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATA Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for PLAIN destinations
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for link-related packets
Tff7b72!Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for resource packets
Tff7b72!Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_RCLTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3PacketReceipt Te6edf3receiptTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3receiptTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
Tff7b72return Te6edf3sentTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3packet_filterTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO: Think long and hard about this.
T8b949e// Is it even strictly necessary with the current
T8b949e// transport rules?
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVETb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_REQTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_PRFTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCETb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CHANNELTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped PLAIN packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hopsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid PLAIN announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3GROUPTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped GROUP packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hopsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid GROUP announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_packet_hashlistTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::packet_filter: packet not previously seenTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::packet_filter: packet previously seen but is SINGLE ANNOUNCETa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffFILTERED duplicate packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: FILTERED dup dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3inboundTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3raw_inTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface T8b949e/*= {Type::NONE}*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: received %d bytesTa5d6ff"Tb4b4b4, Te6edf3raw_inTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3_packets_receivedTb4b4b4;
T8b949e// Heap telemetry: snapshot at entry
Tffa657size_t Te6edf3_heap_at_entry Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// CBA
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_receive_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_callbacksTb4b4b4.Te6edf3_receive_packetTb4b4b4(Te6edf3raw_inTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing receive packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Mutable copy of raw data for IFAC processing
Te6edf3Bytes Te6edf3raw Tff7b72= Te6edf3raw_inTb4b4b4;
T8b949e// If interface access codes are enabled,
T8b949e// we must authenticate each packet.
Tff7b72if Tb4b4b4(Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff2Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72&Tff7b72& Te6edf3interfaceTb4b4b4.Te6edf3ifac_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Check that IFAC flag is set
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x80Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0x80Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(T79c0ff2 Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Extract IFAC
Te6edf3Bytes Te6edf3ifac Tff7b72= Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Generate mask
Te6edf3Bytes Te6edf3mask Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3ifacTb4b4b4,
Te6edf3interfaceTb4b4b4.Te6edf3ifac_keyTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// Unmask payload
Te6edf3Bytes Te6edf3unmasked_rawTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72<Tff7b72= T79c0ff1 Tff7b72|Tff7b72| Te6edf3i Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Unmask header bytes and payload
Te6edf3unmasked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Don't unmask IFAC itself
Te6edf3unmasked_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3raw Tff7b72= Te6edf3unmasked_rawTb4b4b4;
T8b949e// Unset IFAC flag
Tffa657uint8_t Te6edf3new_header0 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x7FTb4b4b4;
Tffa657uint8_t Te6edf3new_header1 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
T8b949e// Re-assemble packet without IFAC bytes
Te6edf3Bytes Te6edf3new_rawTb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header0Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header1Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2 Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Calculate expected IFAC
Te6edf3Bytes Te6edf3expected_signature Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3ifac_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3signTb4b4b4(Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3expected_ifac Tff7b72= Te6edf3expected_signatureTb4b4b4.Te6edf3rightTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Check it
Tff7b72if Tb4b4b4(Te6edf3ifac Tff7b72=Tff7b72= Te6edf3expected_ifacTb4b4b4) Tb4b4b4{
Te6edf3raw Tff7b72= Te6edf3new_rawTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC authentication failed, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: packet too short for IFAC, droppingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If the IFAC flag is not set, but should be, drop the packet
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC required but flag not set, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If the interface does not have IFAC enabled,
T8b949e// check the received packet IFAC flag.
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x80Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0x80Tb4b4b4) Tb4b4b4{
T8b949e// If the flag is set, drop the packet
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC flag set but interface has no IFAC, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72while Tb4b4b4(Te6edf3_jobs_runningTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: sleeping...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(T79c0ff0.0005Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: No identity!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657trueTb4b4b4;
Te6edf3Packet Te6edf3packetTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3DestinationTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4)Tb4b4b4, Te6edf3rawTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet unpack failed!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifndef NDEBUG
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: packet: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3debugStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: destination=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PKT] IN iface=%s sz=%u type=%u ctx=%u hdr=%u dstt=%u hops=%u dst=%s tid=%sTa5d6ff"Tb4b4b4,
Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72? Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ffnoneTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// TODO
T8b949e/*p
if (interface) {
if hasattr(interface, "r_stat_rssi"):
if interface.r_stat_rssi != None:
packet.rssi = interface.r_stat_rssi
if len(Transport.local_client_interfaces) > 0:
Transport.local_client_rssi_cache.append([packet.packet_hash, packet.rssi])
while len(Transport.local_client_rssi_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
Transport.local_client_rssi_cache.pop()
if hasattr(interface, "r_stat_snr"):
if interface.r_stat_rssi != None:
packet.snr = interface.r_stat_snr
if len(Transport.local_client_interfaces) > 0:
Transport.local_client_snr_cache.append([packet.packet_hash, packet.snr])
while len(Transport.local_client_snr_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
Transport.local_client_snr_cache.pop()
}
*/
Tff7b72if Tb4b4b4(Te6edf3_local_client_interfacesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3interface_to_shared_instanceTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e//if (packet_filter(packet)) {
T8b949e// CBA
Tffa657bool Te6edf3accept Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_filter_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3accept Tff7b72= Te6edf3_callbacksTb4b4b4.Te6edf3_filter_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing filter packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3acceptTb4b4b4) Tb4b4b4{
Te6edf3accept Tff7b72= Te6edf3packet_filterTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PKT] DROP callback dst=%s type=%u ctx=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3acceptTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet accepted by filterTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE: Comprehensive firewall for untrusted ingress.
T8b949e//
T8b949e// Three rules:
T8b949e// 1. Addresses that touch trusted local interfaces get whitelisted.
T8b949e// 2. Allowed traffic can only extend the two address whitelists with
T8b949e// destination addresses, never per-packet or per-link identifiers.
T8b949e// 3. Everything else from untrusted ingress gets blocked.
T8b949e//
T8b949e// Note on ratchets: ratchet public keys are embedded in announce
T8b949e// payloads and flow through unchanged since we forward the entire
T8b949e// announce verbatim. Ratchet IDs are derived locally and never
T8b949e// appear as transport-level routing identifiers, so no special
T8b949e// handling is needed here.
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tb4b4b4{
Tffa657bool Te6edf3is_untrusted_ingress Tff7b72= Te6edf3is_boundary_untrusted_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3is_announce Tff7b72= Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4;
Tffa657bool Te6edf3is_backbone_ingress Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_untrusted_ingressTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_announceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_backbone_ingressTb4b4b4) Tb4b4b4{
T8b949e// Real Reticulum destinations answer path requests with a
T8b949e// PATH_RESPONSE announce using the normal announce packet
T8b949e// header shape. Only transport-rebroadcasted responses carry
T8b949e// HEADER_2 and our transport identity. Treat any matching
T8b949e// PATH_RESPONSE for an outstanding discovery request as solicited.
Tffa657bool Te6edf3solicited_path_response Tff7b72= Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSE
Tff7b72&Tff7b72& Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3solicited_path_responseTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: BLOCKED unsolicited backbone announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hdr=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// === UNTRUSTED PACKET: gate against all whitelists ===
Tffa657bool Te6edf3allowed Tff7b72= Tffa657falseTb4b4b4;
T8b949e// LoRa/native RF announces must be accepted so path table can form.
Tff7b72if Tb4b4b4(Te6edf3is_announce Tff7b72&Tff7b72& Tff7b72!Te6edf3is_backbone_ingressTb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Whitelist 1: destination is a local device
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Whitelist 2: destination was mentioned by a local device
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Return traffic: proofs routed via reverse_table
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_reverse_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Return traffic: link proofs and link data via link_table
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Our own control destinations (path requests, tunnel synthesize)
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Our own registered destinations
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// HEADER_2 packet addressed to us as transport node — the
T8b949e// sending node routed this to us so we must accept it even
T8b949e// if we haven't seen this specific destination before
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3allowedTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: BLOCKED backbone pkt dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hdr=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
T8b949e// === TRANSITIVE WHITELIST ===
T8b949e// Keep the firewall state to address whitelists only.
Tff7b72if Tb4b4b4(Te6edf3is_boundary_address_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_announceTb4b4b4) Tb4b4b4{
Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// === TRUSTED LOCAL PACKET ===
T8b949e// Only whitelist destination addresses learned from trusted
T8b949e// local interfaces.
Tff7b72if Tb4b4b4(Te6edf3is_boundary_address_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Heap telemetry: snapshot after boundary filter
Tb4b4b4{
Tffa657size_t Te6edf3_heap_after_boundary Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3_boundary_delta Tff7b72= Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_heap_after_boundary Tff7b72- Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_heap_at_entryTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_boundary_delta Tff7b72< T79c0ff-64Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[HEAP-TEL] boundary: %d bytes (bma=%u phl=%u)Ta5d6ff"Tb4b4b4, Te6edf3_boundary_deltaTb4b4b4, Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// By default, remember packet hashes to avoid routing
T8b949e// loops in the network, using the packet filter.
Tffa657bool Te6edf3remember_packet_hash Tff7b72= Tffa657trueTb4b4b4;
T8b949e// If this packet belongs to a link in our link table,
T8b949e// we'll have to defer adding it to the filter list.
T8b949e// In some cases, we might see a packet over a shared-
T8b949e// medium interface, belonging to a link that transports
T8b949e// or terminates with this instance, but before it would
T8b949e// normally reach us. If the packet is appended to the
T8b949e// filter list at this point, link transport will break.
Tff7b72if Tb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3remember_packet_hash Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// If this is a link request proof, don't add it until
T8b949e// we are sure it's not actually somewhere else in the
T8b949e// routing chain.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOF Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3remember_packet_hash Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3remember_packet_hashTb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_packet_hashlistTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_hashlist_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3_packet_hashlistTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Log ALL non-announce packets arriving from local (non-backbone) interfaces
T8b949e// to diagnose whether Sideband is sending ANY response packets
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLOCAL-IN: dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hdr=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Check special conditions for local clients connected
T8b949e// through a shared Reticulum instance
T8b949e//p from_local_client = (packet.receiving_interface in Transport.local_client_interfaces)
Tffa657bool Te6edf3from_local_client Tff7b72= Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p for_local_client = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.destination_table and Transport.destination_table[packet.destination_hash][2] == 0)
T8b949e//p for_local_client_link = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][4] in Transport.local_client_interfaces)
T8b949e//p for_local_client_link |= (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][2] in Transport.local_client_interfaces)
T8b949e// If packet is anything besides ANNOUNCE then determine if it's destinated for a local destination or link
Tffa657bool Te6edf3for_local_client Tff7b72= Tffa657falseTb4b4b4;
Tffa657bool Te6edf3for_local_client_link Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destination_iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3destination_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_hops Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Destined for a local destination
Te6edf3for_local_client Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72auto Te6edf3link_iter Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_iter Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3LinkEntry Te6edf3link_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3link_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Destined for a local link
Te6edf3for_local_client_link Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Destined for a local link
Te6edf3for_local_client_link Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Determine if packet is proof for local destination???
T8b949e//p proof_for_local_client = (packet.destination_hash in Transport.reverse_table) and (Transport.reverse_table[packet.destination_hash][0] in Transport.local_client_interfaces)
Tffa657bool Te6edf3proof_for_local_client Tff7b72= Tffa657falseTb4b4b4;
Tff7b72auto Te6edf3reverse_iter Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3reverse_iter Tff7b72!Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3reverse_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Proof for local destination???
Te6edf3proof_for_local_client Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Plain broadcast packets from local clients are sent
T8b949e// directly on all attached interfaces, since they are
T8b949e// never injected into transport.
T8b949e// If packet is not destined for a local transport-specific destination
Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// If packet is destination type PLAIN and transport type BROADCAST
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3transport_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tb4b4b4{
T8b949e// Send to all interfaces except the one the packet was recieved on
Tff7b72if Tb4b4b4(Te6edf3from_local_clientTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Broadcasting packet on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// If the packet was not from a local client, send
T8b949e// it directly to all local clients
Tff7b72else Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_local_client_interfacesTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Broadcasting packet on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e////////////////////////////////
T8b949e// TRANSPORT HANDLING
T8b949e////////////////////////////////
T8b949e// General transport handling. Takes care of directing
T8b949e// packets according to transport tables and recording
T8b949e// entries in reverse and link tables.
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3from_local_client Tff7b72|Tff7b72| Te6edf3for_local_client Tff7b72|Tff7b72| Te6edf3for_local_client_linkTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Performing general transport handlingTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// If there is no transport id, but the packet is
T8b949e// for a local client, we generate the transport
T8b949e// id (it was stripped on the previous hop, since
T8b949e// we "spoof" the hop count for clients behind a
T8b949e// shared instance, so they look directly reach-
T8b949e// able), and reinsert, so the normal transport
T8b949e// implementation can handle the packet.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3for_local_clientTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Regenerating transport idTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// If this is a cache request, and we can fullfill
T8b949e// it, do so and stop processing. Otherwise resume
T8b949e// normal processing.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3cache_request_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Cached packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Dropping unsatisfied backbone cache requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e// If the packet is in transport, check whether we
T8b949e// are the designated next hop, and process it
T8b949e// accordingly if we are.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is in transport...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: We are designated next-hopTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destination_iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Found next-hop path to destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DestinationEntryTff7b72& Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3destination_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Bytes Te6edf3next_hop Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Just increase hop count and transmit
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += next_hop
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hopTb4b4b4;
T8b949e//new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72+T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Strip transport headers and transmit
T8b949e//new_flags = (RNS.Packet.HEADER_1) << 6 | (Transport.BROADCAST) << 4 | (packet.flags & 0b00001111)
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = struct.pack("!B", new_flags)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72+T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Just increase hop count and transmit
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72? Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff0 Tff7b72: Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// In firewall mode, never route a packet from backbone back to backbone.
T8b949e// The upstream server sent us this packet because we are the next hop,
T8b949e// so the destination must be on our local side.
Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72&Tff7b72& Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Path table incorrectly points to backbone. Skip forwarding.
Tb4b4b4}
Tff7b72else
Tff7b72#Tff7b72endif
Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is next-hop LINKREQUESTTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hopsTb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
T8b949e// When forwarding a LINKREQUEST through this transport node,
T8b949e// clamp the link MTU signalling to min(prev-hop, next-hop)
T8b949e// interface HW_MTU. Without this, endpoints negotiate a
T8b949e// segment size that exceeds this node's buffer capacity,
T8b949e// causing silent truncation and resource transfer stalls.
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: No next-hop HW MTU, stripping link MTU signallingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: Outbound interface doesn't support MTU config, stripping link MTU signallingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: path=%u ph=%u nh=%u -> clamped=%uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3next_hopTb4b4b4,
Te6edf3outbound_interfaceTb4b4b4,
Te6edf3remaining_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657falseTb4b4b4,
Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] CREATE dst=%s link=%s rem=%u recv=%s out=%s lt=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3remaining_hopsTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is next-hop other typeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_interfaceTb4b4b4,
Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_reverse_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet to next hop...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} T8b949e// firewall mode else
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// FIREWALL MODE: No path to destination. If packet came from
T8b949e// a local device (non-backbone), request the path — but only if
T8b949e// this isn't a link_id (link data is handled by link transport).
Tb4b4b4{
Tffa657bool Te6edf3from_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_backbone Tff7b72&Tff7b72& Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: No path to Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for local device packet. Requesting path.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72else
T8b949e// TODO: There should probably be some kind of REJECT
T8b949e// mechanism here, to signal to the source that their
T8b949e// expected path failed.
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffGot packet in transport, but no known path to final destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff. Dropping packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: We are not designated next-hop so not transportingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Either packet is announce or packet has no next-hop (possibly for a local destination)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// FIREWALL MODE: If this packet came from a local interface and we
T8b949e// have a path to the destination, wrap it with transport headers
T8b949e// and forward it through the backbone as the first transport hop.
T8b949e// Skip ANNOUNCE and PROOF packets — announces have their own handling,
T8b949e// and link proofs (LRPROOF) are handled by the LRPROOF transport code.
T8b949e// Also skip packets destined for locally-registered destinations
T8b949e// (e.g. path request handler) — those must be processed locally.
Tffa657bool Te6edf3is_local_destination Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_MAP)
Te6edf3is_local_destination Tff7b72= Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3dest Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3is_local_destination Tff7b72= Tffa657trueTb4b4b4; Tff7b72breakTb4b4b4; Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_local_destination Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3is_from_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_from_backboneTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destination_iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntryTff7b72& Te6edf3dest_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3destination_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Bytes Te6edf3next_hop Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Build outgoing packet based on remaining hops,
T8b949e// mirroring standard transport forwarding logic.
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Multi-hop: wrap with HEADER_2/TRANSPORT,
T8b949e// setting transport_id = next_hop (the next
T8b949e// transport node's identity hash from announce).
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hopTb4b4b4; T8b949e// insert transport_id
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Single hop (remaining_hops <= 1): destination is
T8b949e// directly reachable. Send as HEADER_1/BROADCAST
T8b949e// (no transport header), matching standard transport
T8b949e// behaviour for final-hop delivery.
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
T8b949e// Create link_table or reverse_table entry for return path
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP
Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hopsTb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: local->backbone path=%u ph=%u nh=%u -> %uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4, Te6edf3next_hopTb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3remaining_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657falseTb4b4b4, Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
T8b949e// Each LINKREQUEST gets its own entry (unique link_id)
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] CREATE local dst=%s link=%s rem=%u recv=%s out=%s lt=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3remaining_hopsTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3_reverse_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Forwarding local packet (Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3remaining_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops, Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytes) to Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3dest_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Only request path if the destination is not a link_id
T8b949e// (link data packets are handled by link transport below,
T8b949e// not by standard transport path lookup).
Tff7b72if Tb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: No path to Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for local packet. Requesting path.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// FIREWALL MODE REVERSE: Packet came from backbone,
T8b949e// check if destination is a local LoRa device and forward it.
Tff7b72if Tb4b4b4(Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destination_iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntryTff7b72& Te6edf3dest_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3destination_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Bytes Te6edf3next_hop Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3dest_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Build properly routed packet based on remaining hops,
T8b949e// mirroring the standard transport forwarding logic.
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Multi-hop: wrap with HEADER_2/TRANSPORT
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hopTb4b4b4; T8b949e// transport_id
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Direct or single-hop: send as HEADER_1
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Create link_table or reverse_table entry for return traffic
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP
Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hopsTb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: backbone->local path=%u ph=%u nh=%u -> %uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4, Te6edf3next_hopTb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3remaining_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657falseTb4b4b4, Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Created link_table entry for backbone LINKREQUEST, link_id=Ta5d6ff" Tff7b72+ Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] CREATE backbone dst=%s link=%s rem=%u recv=%s out=%s lt=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3remaining_hopsTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3_reverse_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Forwarding backbone packet (Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3remaining_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops) to local device for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff via Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3dest_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e// Link transport handling. Directs packets according
T8b949e// to entries in the link tables
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUEST Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking if packet is meant for link transport...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3link_iter Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_iter Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: pkt for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hdr=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3LinkEntryTff7b72& Te6edf3link_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3link_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: entry hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff rem=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff val=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_validatedTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] XPORT pkt=%s type=%u ctx=%u hops=%u recv=%s entry_recv=%s entry_out=%s rem=%u taken=%u val=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_validated Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
T8b949e// If receiving and outbound interface is
T8b949e// the same for this link, direction doesn't
T8b949e// matter, and we simply send the packet on.
Te6edf3Interface Te6edf3outbound_interfaceTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interface Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4) Tb4b4b4{
T8b949e// But check that taken hops matches one
T8b949e// of the expectede values.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hops Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Link inbound/outbound interfaes are same, transporting on same interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If interfaces differ, we transmit on
T8b949e// the opposite interface of what the
T8b949e// packet was received on.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4) Tb4b4b4{
T8b949e// Also check that expected hop count matches
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4) Tb4b4b4{
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: HOP MISMATCH (from outbound) pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4) Tb4b4b4{
T8b949e// Also check that expected hop count matches
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: HOP MISMATCH (from receiving) pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: IFACE MISMATCH recv=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3outbound_interfaceTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: FWD to Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] FWD dst=%s to=%s size=%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Add this packet to the filter hashlist now that
T8b949e// we have determined it's actually our turn to
T8b949e// process it (matching Python Transport line 1544).
Te6edf3_packet_hashlistTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_hashlist_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3_packet_hashlistTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3link_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: DROPPED (no outbound interface resolved)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LINK] DROP dst=%s recv=%s rem=%u taken=%u pkt_hops=%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e////////////////////////////////
T8b949e// LOCAL HANDLING
T8b949e////////////////////////////////
T8b949e// Announce handling. Handles logic related to incoming
T8b949e// announces, queueing rebroadcasts of these, and removal
T8b949e// of queued announce rebroadcasts once handed to the next node.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is ANNOUNCETa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-IN dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3received_fromTb4b4b4;
Tffa657bool Te6edf3announce_valid Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3validate_announceTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[ANNC] IN dst=%s valid=%u ctx=%u hops=%u iface=%s data=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_valid Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e//Destination local_destination({Type::NONE});
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination == None and RNS.Identity.validate_announce(packet):
T8b949e//if (!local_destination && Identity::validate_announce(packet)) {
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3found_local Tff7b72&Tff7b72& Te6edf3announce_validTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3announce_validTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for non-local destination, processing...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3received_from Tff7b72= Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Check if this is a next retransmission from
T8b949e// another node. If it is, we're removing the
T8b949e// announce in question from our pending table
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3_announce_tableTb4b4b4.Te6edf3countTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e//AnnounceEntry& announce_entry = _announce_table[packet.destination_hash()];
Te6edf3AnnounceEntryTff7b72& Te6edf3announce_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_announce_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= Te6edf3announce_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffHeard a local rebroadcast of announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_local_rebroadcasts Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_local_rebroadcasts Tff7b72>Tff7b72= Te6edf3LOCAL_REBROADCASTS_MAXTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMax local rebroadcasts of announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff reached, dropping announce from our tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_hops Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72&Tff7b72& Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72< Te6edf3announce_entryTb4b4b4.Te6edf3_timestampTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasted announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff has been passed on to another node, no further tries neededTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3received_from Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Check if this announce should be inserted into
T8b949e// announce and destination tables
Tffa657bool Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
T8b949e// First, check that the announce is not for a destination
T8b949e// local to this system, and that hops are less than the max
T8b949e// CBA TODO determine why packet destination hash is being searched in destinations again since we entered this logic becuase it did not exist above
T8b949e//if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3found_local Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72< Tb4b4b4(Te6edf3PATHFINDER_MTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72< Tb4b4b4(Te6edf3PATHFINDER_MTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tffa657uint64_t Te6edf3announce_emitted Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3announce_emittedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
T8b949e//p random_blob = packet.data[RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8+10]
Te6edf3Bytes Te6edf3random_blob Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//p random_blobs = []
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3empty_random_blobsTb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3random_blobs Tff7b72= Te6edf3empty_random_blobsTb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
T8b949e//p random_blobs = Transport.destination_table[packet.destination_hash][4]
Te6edf3random_blobs Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_random_blobsTb4b4b4;
T8b949e// If we already have a path to the announced
T8b949e// destination, but the hop count is equal or
T8b949e// less, we'll update our tables.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
T8b949e// Make sure we haven't heard the random
T8b949e// blob before, so announces can't be
T8b949e// replayed to forge paths.
T8b949e// TODO: Check whether this approach works
T8b949e// under all circumstances
T8b949e//p if not random_blob in random_blobs:
Tff7b72if Tb4b4b4(Te6edf3random_blobsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3random_blobTb4b4b4) Tff7b72=Tff7b72= Te6edf3random_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If an announce arrives with a larger hop
T8b949e// count than we already have in the table,
T8b949e// ignore it, unless the path is expired, or
T8b949e// the emission timestamp is more recent.
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3path_expires Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_expiresTb4b4b4;
Tffa657uint64_t Te6edf3path_announce_emitted Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3path_random_blob Tff7b72: Te6edf3random_blobsTb4b4b4) Tb4b4b4{
T8b949e//p path_announce_emitted = max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"))
Te6edf3path_announce_emitted Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3path_announce_emittedTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3from_bytes_big_endianTb4b4b4(Te6edf3path_random_blobTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff5Tb4b4b4, T79c0ff5Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_announce_emitted Tff7b72>Tff7b72= Te6edf3announce_emittedTb4b4b4) Tb4b4b4{
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72>Tff7b72= Te6edf3path_expiresTb4b4b4) Tb4b4b4{
T8b949e// We also check that the announce is
T8b949e// different from ones we've already heard,
T8b949e// to avoid loops in the network
Tff7b72if Tb4b4b4(Te6edf3random_blobsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3random_blobTb4b4b4) Tff7b72=Tff7b72= Te6edf3random_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// TODO: Check that this ^ approach actually
T8b949e// works under all circumstances
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReplacing destination table entry for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with new announce due to expired pathTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_add Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3announce_emitted Tff7b72> Te6edf3path_announce_emittedTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3random_blobsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3random_blobTb4b4b4) Tff7b72=Tff7b72= Te6edf3random_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReplacing destination table entry for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with new announce, since it was more recently emittedTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_add Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If this destination is unknown in our table
T8b949e// we should add it
Te6edf3should_add Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// NOTE: The boundary-mode announce echo blocking that was here
T8b949e// has been removed. The standard random_blob check above
T8b949e// already prevents echoes (same blob = same announce bounced
T8b949e// through backbone). Removing the boundary-specific blocking
T8b949e// allows:
T8b949e// 1. Local TCP clients to receive backbone announces for
T8b949e// destinations that also have LoRa paths.
T8b949e// 2. The V3 destination table to contain the backbone path
T8b949e// when it is equal-or-better, enabling correct transport
T8b949e// routing for TCP client LINKREQUESTs.
T8b949e// LoRa-originated announces that arrive first will still be
T8b949e// preferred (equal hops = first-arrival wins via random_blob),
T8b949e// until the next re-announce cycle changes the path.
Tff7b72if Tb4b4b4(Te6edf3should_addTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3rate_blocked Tff7b72= Tffa657falseTb4b4b4;
T8b949e// TODO
T8b949e/*p
if packet.context != RNS.Packet.PATH_RESPONSE and packet.receiving_interface.announce_rate_target != None:
if not packet.destination_hash in Transport.announce_rate_table:
rate_entry = { "last": now, "rate_violations": 0, "blocked_until": 0, "timestamps": [now]}
Transport.announce_rate_table[packet.destination_hash] = rate_entry
else:
rate_entry = Transport.announce_rate_table[packet.destination_hash]
rate_entry["timestamps"].append(now)
while len(rate_entry["timestamps"]) > Transport.MAX_RATE_TIMESTAMPS:
rate_entry["timestamps"].pop(0)
current_rate = now - rate_entry["last"]
if now > rate_entry["blocked_until"]:
if current_rate < packet.receiving_interface.announce_rate_target:
rate_entry["rate_violations"] += 1
else:
rate_entry["rate_violations"] = std::max(0, rate_entry["rate_violations"]-1)
if rate_entry["rate_violations"] > packet.receiving_interface.announce_rate_grace:
rate_target = packet.receiving_interface.announce_rate_target
rate_penalty = packet.receiving_interface.announce_rate_penalty
rate_entry["blocked_until"] = rate_entry["last"] + rate_target + rate_penalty
rate_blocked = True
else:
rate_entry["last"] = now
else:
rate_blocked = True
*/
Tffa657uint8_t Te6edf3retries Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint8_t Te6edf3announce_hops Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3local_rebroadcasts Tff7b72= T79c0ff0Tb4b4b4;
Tffa657bool Te6edf3block_rebroadcasts Tff7b72= Tffa657falseTb4b4b4;
Te6edf3Interface Te6edf3attached_interface Tff7b72= Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tffa657double Te6edf3retransmit_timeout Tff7b72= Te6edf3now Tff7b72+ Tb4b4b4(Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3PATHFINDER_RWTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3expiresTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4) Tb4b4b4{
Te6edf3expires Tff7b72= Te6edf3now Tff7b72+ Te6edf3AP_PATH_TIMETb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3expires Tff7b72= Te6edf3now Tff7b72+ Te6edf3ROAMING_PATH_TIMETb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3expires Tff7b72= Te6edf3now Tff7b72+ Te6edf3PATHFINDER_ETb4b4b4;
Tb4b4b4}
Te6edf3random_blobsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3random_blobTb4b4b4)Tb4b4b4;
T8b949e// Trim random_blobs to prevent unbounded memory growth
T8b949e// (matching Python: random_blobs = random_blobs[-MAX_RANDOM_BLOBS:])
Tff7b72if Tb4b4b4(Te6edf3random_blobsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3MAX_RANDOM_BLOBSTb4b4b4) Tb4b4b4{
T8b949e// Keep only the MAX_RANDOM_BLOBS blobs with the highest
T8b949e// timestamps (bytes 5-9 big-endian). Extract, sort by
T8b949e// timestamp desc, keep top N, rebuild set.
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3blob_vecTb4b4b4(Te6edf3random_blobsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3random_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3blob_vecTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3blob_vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3aTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3bTb4b4b4) Tb4b4b4{
T8b949e// Sort descending by timestamp (bytes 5-9)
Tffa657uint64_t Te6edf3ts_a Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3from_bytes_big_endianTb4b4b4(Te6edf3aTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff5Tb4b4b4, T79c0ff5Tb4b4b4)Tb4b4b4;
Tffa657uint64_t Te6edf3ts_b Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3from_bytes_big_endianTb4b4b4(Te6edf3bTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff5Tb4b4b4, T79c0ff5Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3ts_a Tff7b72> Te6edf3ts_bTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3random_blobsTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_RANDOM_BLOBS Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3blob_vecTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3random_blobsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3blob_vecTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTrimmed random_blobs to %d entries for %sTa5d6ff"Tb4b4b4, Te6edf3random_blobsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3TransportTff7b72:Tff7b72:Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
T8b949e// Insert announce into announce table for retransmission
Tff7b72if Tb4b4b4(Te6edf3rate_blockedTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBlocking rebroadcast of announce from Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to excessive announce rateTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Suppressing announce rebroadcast queue for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// If the announce is from a local client,
T8b949e// it is announced immediately, but only one time.
Te6edf3retransmit_timeout Tff7b72= Te6edf3nowTb4b4b4;
Te6edf3retries Tff7b72= Te6edf3PATHFINDER_RTb4b4b4;
Tb4b4b4}
Te6edf3AnnounceEntry Te6edf3announce_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3retransmit_timeoutTb4b4b4,
Te6edf3retriesTb4b4b4,
Te6edf3received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3packetTb4b4b4,
Te6edf3local_rebroadcastsTb4b4b4,
Te6edf3block_rebroadcastsTb4b4b4,
Te6edf3attached_interface
Tb4b4b4)Tb4b4b4;
T8b949e// BUG FIX: erase before insert since std::map::insert() is
T8b949e// a no-op when key exists (Python dict assignment overwrites)
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// TODO: Check from_local_client once and store result
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
T8b949e// If this is a path response from a local client,
T8b949e// check if any external interfaces have pending
T8b949e// path requests.
T8b949e//p if packet.destination_hash in Transport.pending_local_path_requests:
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//p desiring_interface = Transport.pending_local_path_requests.pop(packet.destination_hash)
Te6edf3Interface Te6edf3desiring_interface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4)Tb4b4b4;
Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4; T8b949e// CBA FIX: pop() equivalent
Tff7b72if Tb4b4b4(Te6edf3desiring_interfaceTb4b4b4) Tb4b4b4{
Te6edf3attached_interface Tff7b72= Te6edf3desiring_interfaceTb4b4b4;
Te6edf3retransmit_timeout Tff7b72= Te6edf3nowTb4b4b4;
Te6edf3retries Tff7b72= Te6edf3PATHFINDER_RTb4b4b4;
Te6edf3AnnounceEntry Te6edf3announce_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3retransmit_timeoutTb4b4b4,
Te6edf3retriesTb4b4b4,
Te6edf3received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3packetTb4b4b4,
Te6edf3local_rebroadcastsTb4b4b4,
Te6edf3block_rebroadcastsTb4b4b4,
Te6edf3attached_interface
Tb4b4b4)Tb4b4b4;
T8b949e// BUG FIX: erase before insert since std::map::insert() is
T8b949e// a no-op when key exists (Python dict assignment overwrites)
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_identity Tff7b72&Tff7b72& Tff7b72!Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3attached_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3Destination Te6edf3announce_destinationTb4b4b4(Te6edf3announce_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3path_responseTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
Te6edf3attached_interfaceTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3path_responseTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3path_responseTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PATH] RESP local-client dst=%s hops=%u to=%sTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropping local-client path response for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, pending requester interface disappearedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// If we have any local clients connected, we re-
T8b949e// transmit the announce to them immediately
Tff7b72if Tb4b4b4(Te6edf3_local_client_interfacesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
T8b949e//announce_destination.hash(packet.destination_hash());
Te6edf3Destination Te6edf3announce_destinationTb4b4b4(Te6edf3announce_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//announce_destination.hexhash(announce_destination.hash().toHex());
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3context_types Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4;
Te6edf3Bytes Te6edf3announce_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// TODO: Shouldn't the context be PATH_RESPONSE in the first case here?
Tff7b72if Tb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3local_interface Tff7b72: Te6edf3_local_client_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3local_interfaceTb4b4b4) Tb4b4b4{
Te6edf3Packet Te6edf3new_announceTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
Te6edf3local_interfaceTb4b4b4,
Te6edf3announce_dataTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3announce_contextTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3local_interface Tff7b72: Te6edf3_local_client_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3local_interfaceTb4b4b4) Tb4b4b4{
Te6edf3Packet Te6edf3new_announceTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
Te6edf3local_interfaceTb4b4b4,
Te6edf3announce_dataTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3announce_contextTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// If we have any waiting discovery path requests
T8b949e// for this destination, we retransmit to that
T8b949e// interface immediately
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3PathRequestEntryTff7b72& Te6edf3pr_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3attached_interface Tff7b72= Te6edf3pr_entryTb4b4b4.Te6edf3_requesting_interfaceTb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffGot matching announce, answering waiting discovery path request for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
T8b949e//announce_destination.hash(packet.destination_hash());
Te6edf3Destination Te6edf3announce_destinationTb4b4b4(Te6edf3announce_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//announce_destination.hexhash(announce_destination.hash().toHex());
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3context_types Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4;
Te6edf3Bytes Te6edf3announce_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3new_announceTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
Te6edf3attached_interfaceTb4b4b4,
Te6edf3announce_dataTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3new_announceTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA Culling before adding to esnure table does not exceed maxsize
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCaching packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3cachedTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e//TRACE("Adding packet " + packet.get_hash().toHex() + " to packet table");
T8b949e//PacketEntry packet_entry(packet);
T8b949e// CBA ACCUMULATES
T8b949e//_packet_table.insert({packet.get_hash(), packet_entry});
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdding destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff to path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DestinationEntry Te6edf3destination_table_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3expiresTb4b4b4,
Te6edf3random_blobsTb4b4b4,
T8b949e//packet.receiving_interface(),
T8b949e//const_cast<Interface&>(packet.receiving_interface()),
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
T8b949e//packet
Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e// Erase existing entry so insert overwrites (matching Python dict[key]=value)
Tffa657bool Te6edf3path_existed Tff7b72= Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3destination_table_entryTb4b4b4}Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3path_existedTb4b4b4) Tb4b4b4{
Tff7b72+Tff7b72+Te6edf3_destinations_addedTb4b4b4;
Te6edf3cull_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PATH] STORED dst=%s hops=%u iface=%s paths=%u bla=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3announce_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDestination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff is now Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops away via Ta5d6ff" Tff7b72+ Te6edf3received_fromTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: STORED path Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE: Register destinations seen via trusted local interfaces (Whitelist 1)
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_boundary_trusted_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Registered local address Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from local interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e//TRACE("Transport::inbound: Destination " + packet.destination_hash().toHex() + " has data: " + packet.data().toHex());
T8b949e//TRACE("Transport::inbound: Destination " + packet.destination_hash().toHex() + " has text: " + packet.data().toString());
T8b949e// TODO
T8b949e/*
// If the receiving interface is a tunnel, we add the
// announce to the tunnels table
if (packet.receiving_interface().tunnel_id()) {
tunnel_entry = Transport.tunnels[packet.receiving_interface.tunnel_id];
paths = tunnel_entry[2];
paths[packet.destination_hash] = destination_table_entry;
expires = OS::time() + Transport::DESTINATION_TIMEOUT;
tunnel_entry[3] = expires;
DEBUG("Path to " + packet.destination_hash().toHex() + " associated with tunnel " + packet.receiving_interface().tunnel_id().toHex());
}
*/
T8b949e// Call externally registered callbacks from apps
T8b949e// wanting to know when an announce arrives
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Not path response, sending to announce handler...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3handler Tff7b72: Te6edf3_announce_handlersTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking filter of announce handler...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
T8b949e// Check that the announced destination matches
T8b949e// the handlers aspect filter
Tffa657bool Te6edf3execute_callback Tff7b72= Tffa657falseTb4b4b4;
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// If the handlers aspect filter is set to
T8b949e// None, we execute the callback in all cases
Te6edf3execute_callback Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3Bytes Te6edf3handler_expected_hash Tff7b72= Te6edf3DestinationTff7b72:Tff7b72:Te6edf3hash_from_name_and_identityTb4b4b4(Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_identityTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3handler_expected_hashTb4b4b4) Tb4b4b4{
Te6edf3execute_callback Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3execute_callbackTb4b4b4) Tb4b4b4{
T8b949e// CBA TODO Why does app data come from recall instead of from this announce packet?
Te6edf3handlerTff7b72-Tff7b72>Te6edf3received_announceTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3announce_identityTb4b4b4,
Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recall_app_dataTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while processing external announce callback.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for local destination, not processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for local destination, not processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[ANNC] SKIP dst=%s valid=%u reason=local_or_invalidTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_valid Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for link requests to local destinations
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is LINKREQUESTTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking if LINKREQUEST is for local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72autoTff7b72& Te6edf3destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Found local destination for LINKREQUESTTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
T8b949e// CBA iterator over std::set is always const so need to make temporarily mutable
T8b949e//destination.receive(packet);
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72const_castTff7b72<Te6edf3DestinationTff7b72&Tff7b72>Tb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3destinationTb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for data packets to local destinations
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATATa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
T8b949e// Data is destined for a link
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATA for a LINKTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATA for an active LINKTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3linkTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Data is basic (not destined for a link)
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Data is for a local destination
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPacket destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff found, destination is localTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72autoTff7b72& Te6edf3destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet destination type Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff matched, processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72const_castTff7b72<Te6edf3DestinationTff7b72&Tff7b72>Tb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3destinationTb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_ALLTb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_APPTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Ta5d6ff"Ta5d6ffError while executing proof request callback. The contained exception was: Ta5d6ff"Tb4b4b4) Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet destination type Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff mismatch, ignoringTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Local destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff not found, not handling packet locallyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for proofs and link-request proofs
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is LINK PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] IN dst=%s hops=%u recv=%s in_lt=%u for_lcl=%u from_lcl=%uTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4,
Te6edf3for_local_client_link Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4, Te6edf3from_local_client Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
T8b949e// This is a link request proof, check if it
T8b949e// needs to be transported
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3for_local_client_link Tff7b72|Tff7b72| Te6edf3from_local_clientTb4b4b4) Tff7b72&Tff7b72& Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: handling proof for link Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3LinkEntryTff7b72& Te6edf3link_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: recv_iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3interface_match Tff7b72= Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interface_matchTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tffa657size_t Te6edf3expected_size Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3expected_size_with_mtu Tff7b72= Te6edf3expected_size Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: data_size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3expected_sizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff or Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3expected_size_with_mtuTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size_with_mtuTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3signalling_bytesTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size_with_mtuTb4b4b4) Tb4b4b4{
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3peer_pub_bytes Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3Identity Te6edf3peer_identity Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3peer_identityTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: FAILED cannot recall identity for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: peer identity recalled for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3peer_sig_pub_bytes Tff7b72= Te6edf3peer_identityTb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3signed_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3peer_pub_bytes Tff7b72+ Te6edf3peer_sig_pub_bytes Tff7b72+ Te6edf3signalling_bytesTb4b4b4;
Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3peer_identityTb4b4b4.Te6edf3validateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: VALIDATED, forwarding to Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] FWD dst=%s to=%s size=%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw = packet.raw[0:1]
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw = packet.raw().left(1);
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: new_raw size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff flags=0xTa5d6ff" Tff7b72+ Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff dest=Ta5d6ff" Tff7b72+ Te6edf3new_rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4, T79c0ff10Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff16Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3link_entryTb4b4b4.Te6edf3_validated Tff7b72= Tffa657trueTb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: transmit() returned OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: INVALID signature for link Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, dropping proof.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] DROP invalid-signature dst=%sTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} T8b949e// end peer_identity valid
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: UNEXPECTED data_size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (expected Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3expected_sizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff or Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3expected_size_with_mtuTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff), dropping proof.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] DROP bad-size dst=%s data=%u expected=%u/%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3expected_sizeTb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3expected_size_with_mtuTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while transporting link request proof. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: IFACE MISMATCH recv=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected_out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: Proof received on wrong interface, not transporting.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] DROP iface-mismatch dst=%s recv=%s expected=%sTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Not in link_table or transport not enabled — check
T8b949e// if we can deliver it to a local pending link
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: not in link_table or transport not enabled, checking local pending links (transport=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for_lcl=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3for_local_client_linkTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from_lcl=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3from_local_clientTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff in_lt=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[LRPROOF] LOCAL-CHECK dst=%s pending=%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3_pending_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA Must make a copy of _pending_links before traversing since it gets modified
T8b949e//for (auto link : _pending_links) {
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3pending_linksTb4b4b4(Te6edf3_pending_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3pending_linksTb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffChecking for link request handling by pending link %sTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffRequesting pending link to validate proofTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3validate_proofTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_PRFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is RESOURCE PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is regular PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3linkTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3Bytes Te6edf3proof_hashTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3EXPL_LENGTHTb4b4b4) Tb4b4b4{
Te6edf3proof_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Check if this proof needs to be transported
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3from_local_client Tff7b72|Tff7b72| Te6edf3proof_for_local_clientTb4b4b4) Tff7b72&Tff7b72& Te6edf3_reverse_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_reverse_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3reverse_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffProof received on correct interface, transporting it via Ta5d6ff" Tff7b72+ Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] XPORT dst=%s data=%u hops=%u recv=%s out=%sTa5d6ff"Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw = packet.raw[0:1]
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw = packet.raw().left(1);
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//p new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffProof received on wrong interface, not transporting it.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] DROP iface-mismatch dst=%s recv=%s expected=%sTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reverse_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffProof is not candidate for transportingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] LOCAL dst=%s in_rev=%u from_lcl=%u proof_lcl=%uTa5d6ff"Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_reverse_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4, Te6edf3from_local_client Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4, Te6edf3proof_for_local_client Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3cull_receiptsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3receipt_validated Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3proof_hashTb4b4b4) Tb4b4b4{
T8b949e// Only test validation if hash matches
Tff7b72if Tb4b4b4(Te6edf3receiptTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3proof_hashTb4b4b4) Tb4b4b4{
Te6edf3receipt_validated Tff7b72= Te6edf3receiptTb4b4b4.Te6edf3validate_proof_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// TODO: This looks like it should actually
T8b949e// be rewritten when implicit proofs are added.
T8b949e// In case of an implicit proof, we have
T8b949e// to check every single outstanding receipt
Te6edf3receipt_validated Tff7b72= Te6edf3receiptTb4b4b4.Te6edf3validate_proof_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA TODO requires modifying of collection while iterating which is forbidden
Tff7b72if Tb4b4b4(Te6edf3receipt_validatedTb4b4b4) Tb4b4b4{
T8b949e//p if receipt in Transport.receipts:
T8b949e//p Transport.receipts.remove(receipt)
Te6edf3cull_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA since modifying of collection while iterating is forbidden
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Heap telemetry: snapshot at exit
Tb4b4b4{
Tffa657size_t Te6edf3_heap_at_exit Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3_inbound_delta Tff7b72= Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_heap_at_exit Tff7b72- Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_heap_at_entryTb4b4b4;
T8b949e// Log every 100th packet or when delta exceeds threshold
Tff7b72static Tffa657uint32_t Te6edf3_tel_pkt_count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3_tel_pkt_countTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_inbound_delta Tff7b72< T79c0ff-64 Tff7b72|Tff7b72| Tb4b4b4(Te6edf3_tel_pkt_count Tff7b72% T79c0ff100 Tff7b72=Tff7b72= T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[HEAP-TEL] inbound: %d bytes (heap=%u pin=%u bma=%u phl=%u lt=%u revr=%u)Ta5d6ff"Tb4b4b4,
Te6edf3_inbound_deltaTb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3_heap_at_exitTb4b4b4, Te6edf3_packets_receivedTb4b4b4,
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_reverse_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3synthesize_tunnelTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
Bytes interface_hash = interface.get_hash();
Bytes public_key = _identity.get_public_key();
Bytes random_hash = Identity::get_random_hash();
tunnel_id_data = public_key+interface_hash
tunnel_id = RNS.Identity.full_hash(tunnel_id_data)
signed_data = tunnel_id_data+random_hash
signature = Transport.identity.sign(signed_data)
data = signed_data+signature
tnl_snth_dst = RNS.Destination(None, RNS.Destination.OUT, RNS.Destination.PLAIN, Transport.APP_NAME, "tunnel", "synthesize")
packet = RNS.Packet(tnl_snth_dst, data, packet_type = RNS.Packet.DATA, transport_type = RNS.Transport.BROADCAST, header_type = RNS.Packet.HEADER_1, attached_interface = interface)
packet.send()
interface.wants_tunnel = False
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3tunnel_synthesize_handlerTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4, Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
try:
expected_length = RNS.Identity.KEYSIZE//8+RNS.Identity.HASHLENGTH//8+RNS.Reticulum.TRUNCATED_HASHLENGTH//8+RNS.Identity.SIGLENGTH//8
if len(data) == expected_length:
public_key = data[:RNS.Identity.KEYSIZE//8]
interface_hash = data[RNS.Identity.KEYSIZE//8:RNS.Identity.KEYSIZE//8+RNS.Identity.HASHLENGTH//8]
tunnel_id_data = public_key+interface_hash
tunnel_id = RNS.Identity.full_hash(tunnel_id_data)
random_hash = data[RNS.Identity.KEYSIZE//8+RNS.Identity.HASHLENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.HASHLENGTH//8+RNS.Reticulum.TRUNCATED_HASHLENGTH//8]
signature = data[RNS.Identity.KEYSIZE//8+RNS.Identity.HASHLENGTH//8+RNS.Reticulum.TRUNCATED_HASHLENGTH//8:expected_length]
signed_data = tunnel_id_data+random_hash
remote_transport_identity = RNS.Identity(create_keys=False)
remote_transport_identity.load_public_key(public_key)
if remote_transport_identity.validate(signature, signed_data):
Transport.handle_tunnel(tunnel_id, packet.receiving_interface)
except Exception as e:
RNS.log("An error occurred while validating tunnel establishment packet.", RNS.LOG_DEBUG)
RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG)
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3handle_tunnelTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3tunnel_idTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
expires = time.time() + Transport.DESTINATION_TIMEOUT
if not tunnel_id in Transport.tunnels:
RNS.log("Tunnel endpoint "+RNS.prettyhexrep(tunnel_id)+" established.", RNS.LOG_DEBUG)
paths = {}
tunnel_entry = [tunnel_id, interface, paths, expires]
interface.tunnel_id = tunnel_id
Transport.tunnels[tunnel_id] = tunnel_entry
else:
RNS.log("Tunnel endpoint "+RNS.prettyhexrep(tunnel_id)+" reappeared. Restoring paths...", RNS.LOG_DEBUG)
tunnel_entry = Transport.tunnels[tunnel_id]
tunnel_entry[1] = interface
tunnel_entry[3] = expires
interface.tunnel_id = tunnel_id
paths = tunnel_entry[2]
deprecated_paths = []
for destination_hash, path_entry in paths.items():
received_from = path_entry[1]
announce_hops = path_entry[2]
expires = path_entry[3]
random_blobs = path_entry[4]
receiving_interface = interface
packet = path_entry[6]
new_entry = [time.time(), received_from, announce_hops, expires, random_blobs, receiving_interface, packet]
should_add = False
if destination_hash in Transport.destination_table:
old_entry = Transport.destination_table[destination_hash]
old_hops = old_entry[2]
old_expires = old_entry[3]
if announce_hops <= old_hops or time.time() > old_expires:
should_add = True
else:
RNS.log("Did not restore path to "+RNS.prettyhexrep(packet.destination_hash)+" because a newer path with fewer hops exist", RNS.LOG_DEBUG)
else:
if time.time() < expires:
should_add = True
else:
RNS.log("Did not restore path to "+RNS.prettyhexrep(packet.destination_hash)+" because it has expired", RNS.LOG_DEBUG)
if should_add:
Transport.destination_table[destination_hash] = new_entry
RNS.log("Restored path to "+RNS.prettyhexrep(packet.destination_hash)+" is now "+str(announce_hops)+" hops away via "+RNS.prettyhexrep(received_from)+" on "+str(receiving_interface), RNS.LOG_DEBUG)
else:
deprecated_paths.append(destination_hash)
for deprecated_path in deprecated_paths:
RNS.log("Removing path to "+RNS.prettyhexrep(deprecated_path)+" from tunnel "+RNS.prettyhexrep(tunnel_id), RNS.LOG_DEBUG)
paths.pop(deprecated_path)
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_interfaceTb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3_interfacesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Te6edf3_interfacesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Te6edf3_interfacesTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3interfaceTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// CBA TODO set or add transport as listener on interface to receive incoming packets?
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
T8b949e//for (auto iter = _interfaces.begin(); iter != _interfaces.end(); ++iter) {
T8b949e// if ((*iter).get() == interface) {
T8b949e// _interfaces.erase(iter);
T8b949e// TRACE("Transport::deregister_interface: Found and removed interface " + (*iter).get().toString());
T8b949e// break;
T8b949e// }
T8b949e//}
T8b949e//auto iter = _interfaces.find(interface);
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72+Tff7b72+Te6edf3iterTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_destinationTb4b4b4(Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
T8b949e//TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3destinationTb4b4b4.Te6edf3mtuTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3directionTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3registered_destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3registered_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//p raise KeyError("Attempt to register an already registered destination.")
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to register an already registered destination.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA ACCUMULATES
Te6edf3_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//p raise KeyError("Attempt to register an already registered destination.")
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to register an already registered destination.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA ACCUMULATES
Te6edf3_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3destinationTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3_owner Tff7b72&Tff7b72& Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport:register_destination: Announcing destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport:register_destination: Skipping registration (not direction IN) of destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
for (const Destination& destination : _destinations) {
for (auto& [hash, destination] : _destinations) {
TRACE("Transport::register_destination: Listed destination " + destination.toString());
}
*/
T8b949e//TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_destinationTb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72if Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_destinationsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_destination: Found and removed destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_destinationsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_destination: Found and removed destination Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_linkTb4b4b4(Te6edf3LinkTff7b72& Te6edf3linkTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering link Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3initiatorTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_pending_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_active_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3activate_linkTb4b4b4(Te6edf3LinkTff7b72& Te6edf3linkTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Activating link Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_pending_linksTb4b4b4.Te6edf3findTb4b4b4(Te6edf3linkTb4b4b4) Tff7b72!Tff7b72= Te6edf3_pending_linksTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link state for link activation: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_pending_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_active_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAttempted to activate a link that was not in the pending tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Registers an announce handler.
:param handler: Must be an object with an *aspect_filter* attribute and a *received_announce(destination_hash, announced_identity, app_data)* callable. See the :ref:`Announce Example<example-announce>` for more info.
*/
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_announce_handlerTb4b4b4(Te6edf3HAnnounceHandler Te6edf3handlerTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering announce handler Ta5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_handlersTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3handlerTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
Deregisters an announce handler.
:param handler: The announce handler to be deregistered.
*/
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_announce_handlerTb4b4b4(Te6edf3HAnnounceHandler Te6edf3handlerTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering announce handler Ta5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_announce_handlersTb4b4b4.Te6edf3findTb4b4b4(Te6edf3handlerTb4b4b4) Tff7b72!Tff7b72= Te6edf3_announce_handlersTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_announce_handlersTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3handlerTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_announce_handler: Found and removed handlerTa5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Te6edf3Interface Te6edf3TransportTff7b72:Tff7b72:Te6edf3find_interface_from_hashTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3interface_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3should_cache_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO: Rework the caching system. It's currently
T8b949e// not very useful to even cache Resource proofs,
T8b949e// disabling it for now, until redesigned.
T8b949e// if packet.context == RNS.Packet.RESOURCE_PRF:
T8b949e// return True
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// When caching packets to storage, they are written
T8b949e// exactly as they arrived over their interface. This
T8b949e// means that they have not had their hop count
T8b949e// increased yet! Take note of this when reading from
T8b949e// the packet cache.
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4, Tffa657bool Te6edf3force_cache T8b949e/*= false*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffChecking to see if packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff should be cachedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3should_cache_packetTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72|Tff7b72| Te6edf3force_cacheTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3Bytes Te6edf3packet_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_packet_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Te6edf3_packet_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packet_hashTb4b4b4, Te6edf3PacketEntryTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_packet_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3oldest Tff7b72= Te6edf3_packet_tableTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_packet_tableTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iter Tff7b72!Tff7b72= Te6edf3_packet_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72+Tff7b72+Te6edf3iterTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_sent_at Tff7b72< Tb4b4b4(Tff7b72*Te6edf3oldestTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_sent_atTb4b4b4) Tb4b4b4{
Te6edf3oldest Tff7b72= Te6edf3iterTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Tb4b4b4(Tff7b72*Te6edf3oldestTb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4)Tb4b4b4;
Te6edf3_packet_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3oldestTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffSaving packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff to storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3cached Tff7b72= Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3serializeTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3packet_cache_pathTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cachedTb4b4b4) Tb4b4b4{
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3cachedTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError writing packet to cache. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Te6edf3Packet Te6edf3TransportTff7b72:Tff7b72:Te6edf3get_cached_packetTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffLoading packet Ta5d6ff" Tff7b72+ Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from cache storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72auto Te6edf3packet_iter Tff7b72= Te6edf3_packet_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packet_iter Tff7b72=Tff7b72= Te6edf3_packet_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Te6edf3Packet Te6edf3packetTb4b4b4(Te6edf3DestinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4, Tb4b4b4(Tff7b72*Te6edf3packet_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_rawTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4(Tff7b72*Te6edf3packet_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3sent_atTb4b4b4(Tb4b4b4(Tff7b72*Te6edf3packet_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_sent_atTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3cachedTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3packetTb4b4b4;
Tb4b4b4}
Te6edf3_packet_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_iterTb4b4b4)Tb4b4b4;
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72try Tb4b4b4{
T8b949e/*p
packet_hash = RNS.hexrep(packet_hash, delimit=False)
path = RNS.Reticulum.cachepath+"/"+packet_hash
if os.path.isfile(path):
file = open(path, "rb")
cached_data = umsgpack.unpackb(file.read())
file.close()
packet = RNS.Packet(None, cached_data[0])
interface_reference = cached_data[1]
for interface in Transport.interfaces:
if str(interface) == interface_reference:
packet.receiving_interface = interface
return packet
else:
return None
*/
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72if Tb4b4b4(Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packet_hashTb4b4b4) Tff7b72=Tff7b72= Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Te6edf3Packet Te6edf3packetTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3deserializeTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3packet_cache_pathTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3packetTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while getting cached packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3clear_cached_packetTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffClearing packet Ta5d6ff" Tff7b72+ Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from cache storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3_packet_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72try Tb4b4b4{
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3start_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3success Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3remove_fileTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3successTb4b4b4) Tb4b4b4{
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657double Te6edf3diff_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start_timeTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3diff_time Tff7b72< T79c0ff1.0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemove cached packet in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3diff_timeTff7b72*T79c0ff1000Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemove cached packet in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3diff_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while clearing cached packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_request_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PacketTff7b72& Te6edf3cached_packet Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cached_packetTb4b4b4) Tb4b4b4{
T8b949e// If the packet was retrieved from the local
T8b949e// cache, replay it to the Transport instance,
T8b949e// so that it can be directed towards it original
T8b949e// destination.
Te6edf3inboundTb4b4b4(Te6edf3cached_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cached_packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4, Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PacketTff7b72& Te6edf3cached_packet Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cached_packetTb4b4b4) Tb4b4b4{
T8b949e// The packet was found in the local cache,
T8b949e// replay it to the Transport instance.
Te6edf3inboundTb4b4b4(Te6edf3cached_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cached_packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// The packet is not in the local cache,
T8b949e// query the network.
Te6edf3Packet Te6edf3requestTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3packet_hashTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4)Tb4b4b4;
Te6edf3requestTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA also remove cached announce packet if exists
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: *True* if a path to the destination is known, otherwise *False*.
*/
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3has_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The number of hops to the specified destination, or ``RNS.Transport.PATHFINDER_M`` if the number of hops is unknown.
*/
T8b949e/*static*/ Tffa657uint8_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3hops_toTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72return Te6edf3destination_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Te6edf3PATHFINDER_MTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The destination hash as *bytes* for the next hop to the specified destination, or *None* if the next hop is unknown.
*/
T8b949e/*static*/ Te6edf3Bytes Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hopTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72return Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tb4b4b4{Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The interface for the next hop to the specified destination, or *None* if the interface is unknown.
*/
T8b949e/*static*/ Te6edf3Interface Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interfaceTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72return Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interface_bitrateTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interface_hw_mtuTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72else Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_per_bit_latencyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3bitrate Tff7b72= Te6edf3next_hop_interface_bitrateTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bitrate Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(T79c0ff1.0Tff7b72/Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3bitrateTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_per_byte_latencyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3per_bit_latency Tff7b72= Te6edf3next_hop_per_bit_latencyTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3per_bit_latency Tff7b72> T79c0ff0.0Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3per_bit_latencyTff7b72*T79c0ff8.0Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3first_hop_timeoutTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3latency Tff7b72= Te6edf3next_hop_per_byte_latencyTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3latency Tff7b72> T79c0ff0.0Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTU Tff7b72* Te6edf3latency Tff7b72+ Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3DEFAULT_PER_HOP_TIMEOUTTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3DEFAULT_PER_HOP_TIMEOUTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(Tb4b4b4(T79c0ff1.0Tff7b72/Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72*T79c0ff8.0Tb4b4b4)Tff7b72*Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3expire_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DestinationEntry Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3_tables_last_culled Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*p
@staticmethod
def mark_path_unresponsive(destination_hash):
if destination_hash in Transport.destination_table:
Transport.path_states[destination_hash] = Transport.STATE_UNRESPONSIVE
return True
else:
return False
@staticmethod
def mark_path_responsive(destination_hash):
if destination_hash in Transport.destination_table:
Transport.path_states[destination_hash] = Transport.STATE_RESPONSIVE
return True
else:
return False
@staticmethod
def mark_path_unknown_state(destination_hash):
if destination_hash in Transport.destination_table:
Transport.path_states[destination_hash] = Transport.STATE_UNKNOWN
return True
else:
return False
@staticmethod
def path_is_unresponsive(destination_hash):
if destination_hash in Transport.path_states:
if Transport.path_states[destination_hash] == Transport.STATE_UNRESPONSIVE:
return True
return False
*/
T8b949e/*
Requests a path to the destination from the network. If
another reachable peer on the network knows a path, it
will announce it.
:param destination_hash: A destination hash as *bytes*.
:param on_interface: If specified, the path request will only be sent on this interface. In normal use, Reticulum handles this automatically, and this parameter should not be used.
*/
T8b949e///*static*/ void Transport::request_path(const Bytes& destination_hash, const Interface& on_interface /*= {Type::NONE}*/, const Bytes& tag /*= {}*/, bool recursive /*= false*/) {
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3request_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3on_interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3tag T8b949e/*= {}*/Tb4b4b4, Tffa657bool Te6edf3recursive T8b949e/*= false*/Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3request_tagTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3tagTb4b4b4) Tb4b4b4{
Te6edf3request_tag Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3get_random_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3request_tag Tff7b72= Te6edf3tagTb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3path_request_dataTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3path_request_data Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3request_tagTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3path_request_data Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3request_tagTb4b4b4;
Tb4b4b4}
Te6edf3Destination Te6edf3path_request_dstTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpath.requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3packetTb4b4b4(Te6edf3path_request_dstTb4b4b4, Te6edf3on_interfaceTb4b4b4, Te6edf3path_request_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3on_interface Tff7b72&Tff7b72& Te6edf3recursiveTb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
if not hasattr(on_interface, "announce_cap"):
on_interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP
if not hasattr(on_interface, "announce_allowed_at"):
on_interface.announce_allowed_at = 0
if not hasattr(on_interface, "announce_queue"):
on_interface.announce_queue = []
*/
Tffa657bool Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3on_interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3queued_announcesTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking recursive path request on Ta5d6ff" Tff7b72+ Te6edf3on_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to queued announcesTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72< Te6edf3on_interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking recursive path request on Ta5d6ff" Tff7b72+ Te6edf3on_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to active announce capTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//p tx_time = ((len(path_request_data)+RNS.Reticulum.HEADER_MINSIZE)*8) / on_interface.bitrate
Tffa657uint32_t Te6edf3wait_time Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4( Te6edf3on_interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3on_interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3tx_time Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3path_request_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3HEADER_MINSIZETb4b4b4)Tff7b72*T79c0ff8Tb4b4b4) Tff7b72/ Te6edf3on_interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wait_time Tff7b72= Tb4b4b4(Te6edf3tx_time Tff7b72/ Te6edf3on_interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3on_interfaceTb4b4b4)Tb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3now Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_path_requestsTb4b4b4[Te6edf3destination_hashTb4b4b4] Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3request_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3path_request_handlerTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4, Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handlerTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff16Tb4b4b4) Tb4b4b4{ Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: PATH-REQ for Ta5d6ff" Tff7b72+ Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff16Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PATH] REQ dst=%s from=%s local=%u sz=%uTa5d6ff"Tb4b4b4,
Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4, Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72try Tb4b4b4{
T8b949e// If there is at least bytes enough for a destination
T8b949e// hash in the packet, we assume those bytes are the
T8b949e// destination being requested.
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3destination_hash Tff7b72= Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: destination_hash: " + destination_hash.toHex());
T8b949e// If there is also enough bytes for a transport
T8b949e// instance ID and at least one tag byte, we
T8b949e// assume the next bytes to be the trasport ID
T8b949e// of the requesting transport instance.
Te6edf3Bytes Te6edf3requesting_transport_instanceTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72*T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3requesting_transport_instance Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: requesting_transport_instance: " + requesting_transport_instance.toHex());
Tb4b4b4}
Te6edf3Bytes Te6edf3tag_bytesTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3tag_bytesTb4b4b4) Tb4b4b4{
T8b949e//TRACE("Transport::path_request_handler: tag_bytes: " + tag_bytes.toHex());
Tff7b72if Tb4b4b4(Te6edf3tag_bytesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3tag_bytesTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3unique_tag Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3tag_bytesTb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: unique_tag: " + unique_tag.toHex());
Tff7b72if Tb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3unique_tagTb4b4b4) Tff7b72=Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3unique_tagTb4b4b4)Tb4b4b4;
Te6edf3path_requestTb4b4b4(
Te6edf3destination_hashTb4b4b4,
Te6edf3from_local_clientTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3requesting_transport_instanceTb4b4b4,
Te6edf3tag_bytes
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring duplicate path request for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with tag Ta5d6ff" Tff7b72+ Te6edf3unique_tagTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring tagless path request for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while handling path request. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3path_requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tffa657bool Te6edf3is_from_local_clientTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3attached_interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3requestor_transport_id T8b949e/*= {}*/Tb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3tag T8b949e/*= {}*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3should_search_for_unknown Tff7b72= Tffa657falseTb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3interface_strTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attached_interfaceTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3attached_can_discover Tff7b72= Tffa657trueTb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3attached_can_discover Tff7b72= Te6edf3is_boundary_trusted_interfaceTb4b4b4(Te6edf3attached_interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3attached_can_discover Tff7b72&Tff7b72& Tb4b4b4(Te6edf3attached_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72& Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3DISCOVER_PATHS_FORTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: interface allows searching for unknown pathsTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_search_for_unknown Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Te6edf3interface_str Tff7b72= Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3destination_exists_on_local_client Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_local_client_interfacesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DestinationEntryTff7b72& Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3destination_exists_on_local_client Tff7b72= Tffa657trueTb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_pending_local_path_requestsTb4b4b4[Te6edf3destination_hashTb4b4b4] Tff7b72= Te6edf3attached_interface Tff7b72? Te6edf3attached_interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72: Te6edf3BytesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry not found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == destination_hash), None)
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Te6edf3Destination Te6edf3local_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3local_destination Tff7b72= Te6edf3destinationTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
Tff7b72if Tb4b4b4(Te6edf3local_destinationTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72autoTff7b72& Te6edf3local_destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3local_destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Tffa657trueTb4b4b4, Te6edf3attached_interfaceTb4b4b4, Te6edf3tagTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAnswering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, destination is local to this systemTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e//p elif (RNS.Reticulum.transport_enabled() or is_from_local_client) and (destination_hash in Transport.destination_table):
Tff7b72else Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3is_from_local_clientTb4b4b4) Tff7b72&Tff7b72& Te6edf3destination_iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DestinationEntryTff7b72& Te6edf3destination_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3destination_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72const Te6edf3PacketTff7b72& Te6edf3announce_packet Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3announce_packetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3BytesTff7b72& Te6edf3next_hop Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3announce_packetTb4b4b4) Tb4b4b4{
T8b949e// Cache file missing or corrupt — remove the stale entry and bail
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffpath_request: removing stale path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to missing announce packet cacheTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_iterTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3receiving_interface Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attached_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMING Tff7b72&Tff7b72& Te6edf3attached_interface Tff7b72=Tff7b72= Te6edf3receiving_interfaceTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffNot answering path request on roaming-mode interface, since next hop is on same roaming-mode interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3requestor_transport_id Tff7b72&Tff7b72& Te6edf3destination_entryTb4b4b4.Te6edf3_received_from Tff7b72=Tff7b72= Te6edf3requestor_transport_idTb4b4b4) Tb4b4b4{
T8b949e// TODO: Find a bandwidth efficient way to invalidate our
T8b949e// known path on this signal. The obvious way of signing
T8b949e// path requests with transport instance keys is quite
T8b949e// inefficient. There is probably a better way. Doing
T8b949e// path invalidation here would decrease the network
T8b949e// convergence time. Maybe just drop it?
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffNot answering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, since next hop is the requestorTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAnswering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, path is knownTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: PATH-RESP for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3retries Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RTb4b4b4;
Tffa657uint8_t Te6edf3local_rebroadcasts Tff7b72= T79c0ff0Tb4b4b4;
Tffa657bool Te6edf3block_rebroadcasts Tff7b72= Tffa657trueTb4b4b4;
T8b949e// BUG FIX: Must use DestinationEntry._hops, NOT cached announce_packet.hops().
T8b949e// The cached packet's raw bytes still have the pre-increment wire hops,
T8b949e// because Packet::hops(val) only updates an in-memory field, not raw[1].
T8b949e// Python Transport.py explicitly sets packet.hops = path_table[dest][IDX_PT_HOPS]
T8b949e// after retrieving the cached packet (line 2736), but C++ was using the
T8b949e// stale raw-byte value. This caused PATH_RESPONSE to report fewer hops than
T8b949e// actual, making the sender's expected_hops too low, which then caused
T8b949e// LRPROOF hop-count validation to fail silently.
Tffa657uint8_t Te6edf3announce_hops Tff7b72= Te6edf3destination_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Tffa657double Te6edf3retransmit_timeout Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_from_local_clientTb4b4b4) Tb4b4b4{
Te6edf3retransmit_timeout Tff7b72= Te6edf3nowTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// TODO: Look at this timing
Te6edf3retransmit_timeout Tff7b72= Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_GRACE T8b949e/*+ (RNS.rand() * Transport.PATHFINDER_RW)*/Tb4b4b4;
Tb4b4b4}
T8b949e// This handles an edge case where a peer sends a past
T8b949e// request for a destination just after an announce for
T8b949e// said destination has arrived, but before it has been
T8b949e// rebroadcast locally. In such a case the actual announce
T8b949e// is temporarily held, and then reinserted when the path
T8b949e// request has been served to the peer.
Tff7b72auto Te6edf3announce_iter Tff7b72= Te6edf3_announce_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_iter Tff7b72!Tff7b72= Te6edf3_announce_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3AnnounceEntryTff7b72& Te6edf3held_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3announce_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_held_announcesTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3held_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// BUG FIX: Must erase old entry before insert(),
T8b949e// since std::map::insert() is a no-op when key exists.
T8b949e// Python dict assignment overwrites, but C++ insert does not.
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3announce_iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3AnnounceEntry Te6edf3announce_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3retransmit_timeoutTb4b4b4,
Te6edf3retriesTb4b4b4,
Te6edf3destination_entryTb4b4b4.Te6edf3_received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3announce_packetTb4b4b4,
Te6edf3local_rebroadcastsTb4b4b4,
Te6edf3block_rebroadcastsTb4b4b4,
Te6edf3attached_interface
Tb4b4b4)Tb4b4b4;
T8b949e// ESP32/FIREWALL_MODE FIX: For requests from LAN-side interfaces,
T8b949e// send the PATH_RESPONSE immediately rather than waiting for the
T8b949e// jobs() loop to process the announce_table entry. This includes
T8b949e// Local TCP clients and LoRa. Backbone/WAN interfaces remain
T8b949e// suppressed below to preserve the boundary firewall.
Tffa657bool Te6edf3send_immediate_path_response Tff7b72= Te6edf3is_from_local_clientTb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72if Tb4b4b4(Te6edf3attached_interface Tff7b72&Tff7b72& Tff7b72!Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3attached_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3send_immediate_path_response Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3send_immediate_path_responseTb4b4b4) Tb4b4b4{
Te6edf3Identity Te6edf3imm_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Destination Te6edf3imm_destinationTb4b4b4(Te6edf3imm_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3imm_packetTb4b4b4(
Te6edf3imm_destinationTb4b4b4,
Te6edf3attached_interfaceTb4b4b4,
Te6edf3announce_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3announce_packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3imm_packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3announce_hopsTb4b4b4)Tb4b4b4;
Te6edf3imm_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ff[PATH] RESP dst=%s hops=%u to=%s local=%uTa5d6ff"Tb4b4b4,
Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tffa657unsignedTb4b4b4)Te6edf3announce_hopsTb4b4b4, Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3is_from_local_client Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: PATH-RESP immediate send for Ta5d6ff" Tff7b72+ Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff to Ta5d6ff" Tff7b72+ Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Remove from announce_table since we already sent it
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72if Tb4b4b4(Te6edf3attached_interface Tff7b72&Tff7b72& Te6edf3is_boundary_trusted_interfaceTb4b4b4(Te6edf3attached_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Keep a queued local retry even after an immediate send. On
T8b949e// repeated LAN-to-WAN requests the immediate response can arrive
T8b949e// before the fresh local client has fully entered path discovery,
T8b949e// but a scheduled retry one job tick later is accepted.
Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeout Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3_announces_check_intervalTb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Suppressing queued path-response announce for Ta5d6ff" Tff7b72+ Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else
T8b949e// CBA ACCUMULATES
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3is_from_local_clientTb4b4b4) Tb4b4b4{
T8b949e// Forward path request on all interfaces
T8b949e// except the local client
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffForwarding path request from local client for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff to all other interfacesTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3request_tag Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3get_random_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(FIREWALL_MODE)
Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Tb4b4b4{
Te6edf3destination_hashTb4b4b4,
Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_TIMEOUTTb4b4b4,
Te6edf3attached_interface
Tb4b4b4}Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72!Tff7b72= Te6edf3attached_interfaceTb4b4b4) Tb4b4b4{
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3interfaceTb4b4b4, Te6edf3request_tagTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3should_search_for_unknownTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: searching for unknown path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72!Tff7b72= Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffThere is already a waiting path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on behalf of path requestTa5d6ff" Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Forward path request on all interfaces
T8b949e// except the requestor interface
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAttempting to discover unknown path to destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on behalf of path requestTa5d6ff" Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
T8b949e//p pr_entry = { "destination_hash": destination_hash, "timeout": time.time()+Transport.PATH_REQUEST_TIMEOUT, "requesting_interface": attached_interface }
T8b949e//p _discovery_path_requests[destination_hash] = pr_entry;
T8b949e// CBA ACCUMULATES
Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Tb4b4b4{
Te6edf3destination_hashTb4b4b4,
Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_TIMEOUTTb4b4b4,
Te6edf3attached_interface
Tb4b4b4}Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(FIREWALL_MODE)
T8b949e// BOUNDARY: Track this destination in Whitelist 2 so the path
T8b949e// response announce from the backbone will be allowed through
Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
T8b949e// CBA EXPERIMENTAL forwarding path requests even on requestor interface in order to support
T8b949e// path-finding over LoRa mesh
T8b949e//if (interface != attached_interface) {
Tff7b72if Tb4b4b4(Tffa657trueTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request: requesting path on interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Use the previously extracted tag from this path request
T8b949e// on the new path requests as well, to avoid potential loops
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3interfaceTb4b4b4, Te6edf3tagTb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request: not requesting path on same interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_from_local_client Tff7b72&Tff7b72& Te6edf3_local_client_interfacesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0
Tff7b72&Tff7b72& Te6edf3attached_interface Tff7b72&Tff7b72& Te6edf3is_boundary_untrusted_interfaceTb4b4b4(Te6edf3attached_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBOUNDARY: Dropping unknown path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff from untrusted interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_from_local_client Tff7b72&Tff7b72& Te6edf3_local_client_interfacesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Forward the path request on all local
T8b949e// client interfaces
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffForwarding path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff to local clientsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_local_client_interfacesTb4b4b4) Tb4b4b4{
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, no path knownTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3from_local_clientTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3is_local_client_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3is_local_client_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_local_client_interfacesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3interfaceTb4b4b4) Tff7b72!Tff7b72= Te6edf3_local_client_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3parent_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3parent_interfaceTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3is_local_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3interface_to_shared_instanceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3detach_interfacesTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
detachable_interfaces = []
for interface in Transport.interfaces:
// Currently no rules are being applied
// here, and all interfaces will be sent
// the detach call on RNS teardown.
if True:
detachable_interfaces.append(interface)
else:
pass
for interface in Transport.local_client_interfaces:
// Currently no rules are being applied
// here, and all interfaces will be sent
// the detach call on RNS teardown.
if True:
detachable_interfaces.append(interface)
else:
pass
for interface in detachable_interfaces:
interface.detach()
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3shared_connection_disappearedTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
for link in Transport.active_links:
link.teardown()
for link in Transport.pending_links:
link.teardown()
Transport.announce_table = {}
Transport.destination_table = {}
Transport.reverse_table = {}
Transport.link_table = {}
Transport.held_announces = {}
Transport.announce_handlers = []
Transport.tunnels = {}
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3shared_connection_reappearedTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
if Transport.owner.is_connected_to_shared_instance:
for registered_destination in Transport.destinations:
if registered_destination.type == RNS.Destination.SINGLE:
registered_destination.announce(path_response=True)
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3drop_announce_queuesTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*p
for interface in Transport.interfaces:
if hasattr(interface, "announce_queue") and interface.announce_queue != None:
na = len(interface.announce_queue)
if na > 0:
if na == 1:
na_str = "1 announce"
else:
na_str = str(na)+" announces"
interface.announce_queue = []
RNS.log("Dropped "+na_str+" on "+str(interface), RNS.LOG_VERBOSE)
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657uint64_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3announce_emittedTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e//p random_blob = packet.data[RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8+10]
T8b949e//p announce_emitted = int.from_bytes(random_blob[5:10], "big")
Te6edf3Bytes Te6edf3random_blob Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72+Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, T79c0ff10Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3random_blobTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3OSTff7b72:Tff7b72:Te6edf3from_bytes_big_endianTb4b4b4(Te6edf3random_blobTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff5Tb4b4b4, T79c0ff5Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_packet_hashlistTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
T8b949e/*p
if not Transport.owner.is_connected_to_shared_instance:
if hasattr(Transport, "saving_packet_hashlist"):
wait_interval = 0.2
wait_timeout = 5
wait_start = time.time()
while Transport.saving_packet_hashlist:
time.sleep(wait_interval)
if time.time() > wait_start+wait_timeout:
RNS.log("Could not save packet hashlist to storage, waiting for previous save operation timed out.", RNS.LOG_ERROR)
return False
try:
Transport.saving_packet_hashlist = True
save_start = time.time()
if not RNS.Reticulum.transport_enabled():
Transport.packet_hashlist = []
else:
RNS.log("Saving packet hashlist to storage...", RNS.LOG_DEBUG)
packet_hashlist_path = RNS.Reticulum.storagepath+"/packet_hashlist"
file = open(packet_hashlist_path, "wb")
file.write(umsgpack.packb(Transport.packet_hashlist))
file.close()
save_time = time.time() - save_start
if save_time < 1:
time_str = str(round(save_time*1000,2))+"ms"
else:
time_str = str(round(save_time,2))+"s"
RNS.log("Saved packet hashlist in "+time_str, RNS.LOG_DEBUG)
except Exception as e:
RNS.log("Could not save packet hashlist to storage, the contained exception was: "+str(e), RNS.LOG_ERROR)
Transport.saving_packet_hashlist = False
*/
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e//#define CUSTOM 1
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3read_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::read_path_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3destination_table_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e/*p
serialised_destinations = []
try:
file = open(destination_table_path, "rb")
serialised_destinations = umsgpack.unpackb(file.read())
file.close()
for serialised_entry in serialised_destinations:
destination_hash = serialised_entry[0]
if len(destination_hash) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
timestamp = serialised_entry[1]
received_from = serialised_entry[2]
hops = serialised_entry[3]
expires = serialised_entry[4]
random_blobs = serialised_entry[5]
receiving_interface = Transport.find_interface_from_hash(serialised_entry[6])
announce_packet = Transport.get_cached_packet(serialised_entry[7])
if announce_packet != None and receiving_interface != None:
announce_packet.unpack()
// We increase the hops, since reading a packet
// from cache is equivalent to receiving it again
// over an interface. It is cached with it's non-
// increased hop-count.
announce_packet.hops += 1
Transport.destination_table[destination_hash] = [timestamp, received_from, hops, expires, random_blobs, receiving_interface, announce_packet]
RNS.log("Loaded path table entry for "+RNS.prettyhexrep(destination_hash)+" from storage", RNS.LOG_DEBUG)
else:
RNS.log("Could not reconstruct path table entry from storage for "+RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
if announce_packet == None:
RNS.log("The announce packet could not be loaded from cache", RNS.LOG_DEBUG)
if receiving_interface == None:
RNS.log("The interface is no longer available", RNS.LOG_DEBUG)
*/
Tff7b72try Tb4b4b4{
Tff7b72#Tff7b72if CUSTOM
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer capacity %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3capacityTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3read_fileTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: read: %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer addr: 0x%XTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer size %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("SERIALIZED: destination_table");
T8b949e//TRACE(Persistence::_buffer.toString());
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifdef USE_MSGPACK
Te6edf3DeserializationError Te6edf3error Tff7b72= Te6edf3deserializeMsgPackTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3DeserializationError Te6edf3error Tff7b72= Te6edf3deserializeJsonTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: doc size: %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3errorTb4b4b4) Tb4b4b4{
T8b949e// Calculate crc for dirty-checking before write
Te6edf3_destination_table_crc Tff7b72= Te6edf3CrcTff7b72:Tff7b72:Te6edf3crc32Tb4b4b4(T79c0ff0Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_destination_table Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3asTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72>Tff7b72>Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else T8b949e// CUSTOM
T8b949e// Calculate crc for dirty-checking before write
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3deserializeTb4b4b4(Te6edf3_destination_tableTb4b4b4, Te6edf3destination_table_pathTb4b4b4, Te6edf3_destination_table_crcTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: successfully deserialized path table with %d entriesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3invalid_pathsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifndef NDEBUG
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: entry: %s = %sTa5d6ff"Tb4b4b4, Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3destination_entryTb4b4b4.Te6edf3debugStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// CBA If announce packet load fails then remove destination entry (it's useless without announce packet)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3destination_entryTb4b4b4.Te6edf3announce_packetTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// remove destination
Te6edf3WARNINGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: removing invalid path to %s due to missing announce packetTa5d6ff"Tb4b4b4, Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3invalid_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA If receiving interface is not found then remove destination entry (it's useless without interface)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3destination_entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// remove destination
Te6edf3WARNINGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: removing invalid path to %s due to missing receiving interfaceTa5d6ff"Tb4b4b4, Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3invalid_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3invalid_pathsTb4b4b4) Tb4b4b4{
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Enforce maxsize on loaded paths (trim oldest if over limit)
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: trimming loaded path table from %d to %d entriesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_path_table_maxsizeTb4b4b4)Tb4b4b4;
Te6edf3cull_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Memory diagnostic after path table load
Tffa657size_t Te6edf3total_blobs Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3entryTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Te6edf3total_blobs Tff7b72+Tff7b72= Te6edf3entryTb4b4b4.Te6edf3_random_blobsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: path table: %d entries, %d total random_blobs (est. %d bytes)Ta5d6ff"Tb4b4b4,
Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3total_blobsTb4b4b4, Te6edf3total_blobs Tff7b72* T79c0ff90Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: failed to deserializeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if CUSTOM
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: destination table read failedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else T8b949e// CUSTOM
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffLoaded %d valid path table entries from storageTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffCould not load destination table from storage, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3success Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72if Tb4b4b4(Te6edf3_saving_path_tableTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3wait_interval Tff7b72= T79c0ff0.2Tb4b4b4;
Tffa657double Te6edf3wait_timeout Tff7b72= T79c0ff5Tb4b4b4;
Tffa657double Te6edf3wait_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_saving_path_tableTb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(Te6edf3wait_intervalTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3wait_start Tff7b72+ Te6edf3wait_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffCould not save path table to storage, waiting for previous save operation timed out.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72try Tb4b4b4{
Te6edf3_saving_path_table Tff7b72= Tffa657trueTb4b4b4;
Tffa657double Te6edf3save_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaving %d path table entries to storage...Ta5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Enforce maxpersist: create a trimmed copy for serialization
T8b949e// keeping only the most recently used entries (by timestamp)
Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72> Te6edf3persist_tableTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3_path_table_maxpersistTb4b4b4) Tb4b4b4{
Te6edf3persist_table Tff7b72= Te6edf3_destination_tableTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Sort by timestamp descending, keep only maxpersist entries
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72>Tff7b72> Te6edf3sorted_entriesTb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_entriesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3sorted_entriesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72>Tff7b72& Te6edf3aTb4b4b4, Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72>Tff7b72& Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestamp Tff7b72> Te6edf3bTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestampTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3_path_table_maxpersist Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3sorted_entriesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3persist_tableTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3sorted_entriesTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTrimmed path table from %d to %d entries for persistenceTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3persist_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*p
serialised_destinations = []
for destination_hash in Transport.destination_table:
// Get the destination entry from the destination table
de = Transport.destination_table[destination_hash]
interface_hash = de[5].get_hash()
// Only store destination table entry if the associated
// interface is still active
interface = Transport.find_interface_from_hash(interface_hash)
if interface != None:
// Get the destination entry from the destination table
de = Transport.destination_table[destination_hash]
timestamp = de[0]
received_from = de[1]
hops = de[2]
expires = de[3]
random_blobs = de[4]
packet_hash = de[6].get_hash()
serialised_entry = [
destination_hash,
timestamp,
received_from,
hops,
expires,
random_blobs,
interface_hash,
packet_hash
]
serialised_destinations.append(serialised_entry)
Transport.cache(de[6], force_cache=True)
destination_table_path = RNS.Reticulum.storagepath+"/destination_table"
file = open(destination_table_path, "wb")
file.write(umsgpack.packb(serialised_destinations))
file.close()
*/
Tff7b72#Tff7b72if CUSTOM
Tb4b4b4{
Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3setTb4b4b4(Te6edf3persist_tableTb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: doc size %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3memoryUsageTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//size_t size = 8192;
Tffa657size_t Te6edf3size Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3capacityTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: obtaining buffer size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3sizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint8_tTff7b72* Te6edf3buffer Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3writableTb4b4b4(Te6edf3sizeTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer addr: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657longTb4b4b4)Te6edf3bufferTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef USE_MSGPACK
Tffa657size_t Te6edf3length Tff7b72= Te6edf3serializeMsgPackTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3bufferTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tffa657size_t Te6edf3length Tff7b72= Te6edf3serializeJsonTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3bufferTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: serialized %d bytesTa5d6ff"Tb4b4b4, Te6edf3lengthTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3length Tff7b72< Te6edf3sizeTb4b4b4) Tb4b4b4{
Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3resizeTb4b4b4(Te6edf3lengthTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer addr: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657longTb4b4b4)Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("SERIALIZED: destination_table");
T8b949e//TRACE(Persistence::_buffer.toString());
Tff7b72#Tff7b72endif
T8b949e// Check crc to see if data has changed before writing
Tffa657uint32_t Te6edf3crc Tff7b72= Te6edf3CrcTff7b72:Tff7b72:Te6edf3crc32Tb4b4b4(T79c0ff0Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_table_crc Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3crc Tff7b72=Tff7b72= Te6edf3_destination_table_crcTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: no change detected, skipping writeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3write_fileTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4) Tff7b72=Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: wrote %d entries, %d bytesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_destination_table_crc Tff7b72= Te6edf3crcTb4b4b4;
Te6edf3success Tff7b72= Tffa657trueTb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
T8b949e//TRACE("FILE: destination_table");
T8b949e//if (OS::read_file("/destination_table", Persistence::_buffer) > 0) {
T8b949e// TRACE(Persistence::_buffer.toString());
T8b949e//}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: write failedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: failed to serializeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else T8b949e// CUSTOM
Tffa657uint32_t Te6edf3crc Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3crcTb4b4b4(Te6edf3persist_tableTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_table_crc Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3crc Tff7b72=Tff7b72= Te6edf3_destination_table_crcTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: no change detected, skipping writeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: change detected, writing...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3serializeTb4b4b4(Te6edf3persist_tableTb4b4b4, Te6edf3destination_table_pathTb4b4b4, Te6edf3_destination_table_crcTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: wrote %d entries, %d bytesTa5d6ff"Tb4b4b4, Te6edf3persist_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Tff7b72if Tb4b4b4(Te6edf3successTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3save_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3save_startTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3save_time Tff7b72< T79c0ff1.0Tb4b4b4) Tb4b4b4{
T8b949e//DEBUG("Saved " + std::to_string(_destination_table.size()) + " path table entries in " + std::to_string(OS::round(save_time * 1000, 1)) + " ms");
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaved %d path table entries in %d msTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3save_timeTff7b72*T79c0ff1000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//DEBUG("Saved " + std::to_string(_destination_table.size()) + " path table entries in " + std::to_string(OS::round(save_time, 1)) + " s");
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaved %d path table entries in %d sTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3save_timeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffCould not save path table to storage, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3_saving_path_table Tff7b72= Tffa657falseTb4b4b4;
Tff7b72return Te6edf3successTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3read_tunnel_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::read_tunnel_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
T8b949e/*p
tunnel_table_path = RNS.Reticulum.storagepath+"/tunnels"
if os.path.isfile(tunnel_table_path) and not Transport.owner.is_connected_to_shared_instance:
serialised_tunnels = []
try:
file = open(tunnel_table_path, "rb")
serialised_tunnels = umsgpack.unpackb(file.read())
file.close()
for serialised_tunnel in serialised_tunnels:
tunnel_id = serialised_tunnel[0]
interface_hash = serialised_tunnel[1]
serialised_paths = serialised_tunnel[2]
expires = serialised_tunnel[3]
tunnel_paths = {}
for serialised_entry in serialised_paths:
destination_hash = serialised_entry[0]
timestamp = serialised_entry[1]
received_from = serialised_entry[2]
hops = serialised_entry[3]
expires = serialised_entry[4]
random_blobs = serialised_entry[5]
receiving_interface = Transport.find_interface_from_hash(serialised_entry[6])
announce_packet = Transport.get_cached_packet(serialised_entry[7])
if announce_packet != None:
announce_packet.unpack()
// We increase the hops, since reading a packet
// from cache is equivalent to receiving it again
// over an interface. It is cached with it's non-
// increased hop-count.
announce_packet.hops += 1
tunnel_path = [timestamp, received_from, hops, expires, random_blobs, receiving_interface, announce_packet]
tunnel_paths[destination_hash] = tunnel_path
tunnel = [tunnel_id, None, tunnel_paths, expires]
Transport.tunnels[tunnel_id] = tunnel
if len(Transport.destination_table) == 1:
specifier = "entry"
else:
specifier = "entries"
RNS.log("Loaded "+str(len(Transport.tunnels))+" tunnel table "+specifier+" from storage", RNS.LOG_VERBOSE)
except Exception as e:
RNS.log("Could not load tunnel table from storage, the contained exception was: "+str(e), RNS.LOG_ERROR)
*/
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_tunnel_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
T8b949e/*p
if not Transport.owner.is_connected_to_shared_instance:
if hasattr(Transport, "saving_tunnel_table"):
wait_interval = 0.2
wait_timeout = 5
wait_start = time.time()
while Transport.saving_tunnel_table:
time.sleep(wait_interval)
if time.time() > wait_start+wait_timeout:
RNS.log("Could not save tunnel table to storage, waiting for previous save operation timed out.", RNS.LOG_ERROR)
return False
try:
Transport.saving_tunnel_table = True
save_start = time.time()
RNS.log("Saving tunnel table to storage...", RNS.LOG_DEBUG)
serialised_tunnels = []
for tunnel_id in Transport.tunnels:
te = Transport.tunnels[tunnel_id]
interface = te[1]
tunnel_paths = te[2]
expires = te[3]
if interface != None:
interface_hash = interface.get_hash()
else:
interface_hash = None
serialised_paths = []
for destination_hash in tunnel_paths:
de = tunnel_paths[destination_hash]
timestamp = de[0]
received_from = de[1]
hops = de[2]
expires = de[3]
random_blobs = de[4]
packet_hash = de[6].get_hash()
serialised_entry = [
destination_hash,
timestamp,
received_from,
hops,
expires,
random_blobs,
interface_hash,
packet_hash
]
serialised_paths.append(serialised_entry)
Transport.cache(de[6], force_cache=True)
serialised_tunnel = [tunnel_id, interface_hash, serialised_paths, expires]
serialised_tunnels.append(serialised_tunnel)
tunnels_path = RNS.Reticulum.storagepath+"/tunnels"
file = open(tunnels_path, "wb")
file.write(umsgpack.packb(serialised_tunnels))
file.close()
save_time = time.time() - save_start
if save_time < 1:
time_str = str(round(save_time*1000,2))+" ms"
else:
time_str = str(round(save_time,2))+" s"
RNS.log("Saved "+str(len(serialised_tunnels))+" tunnel table entries in "+time_str, RNS.LOG_DEBUG)
except Exception as e:
RNS.log("Could not save tunnel table to storage, the contained exception was: "+str(e), RNS.LOG_ERROR)
Transport.saving_tunnel_table = False
*/
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3persist_dataTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::persist_data()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3write_packet_hashlistTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3write_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3write_tunnel_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3clean_cachesTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// CBA Remove cached packets no longer in path list
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTff7b72> Te6edf3files Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3list_directoryTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3file Tff7b72: Te6edf3filesTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches: Checking for use of cached packet Ta5d6ff" Tff7b72+ Te6edf3fileTb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3found Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3compareTb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_announce_packetTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3found Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3foundTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches: No matching path found, removing cached packet Ta5d6ff" Tff7b72+ Te6edf3fileTb4b4b4)Tb4b4b4;
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3fileTb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3remove_fileTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3dump_statsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3dump_heap_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3memory Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3flash Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_last_memory Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_last_memory Tff7b72= Te6edf3memoryTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_last_flash Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_last_flash Tff7b72= Te6edf3flashTb4b4b4;
Tb4b4b4}
T8b949e// memory
T8b949e// storage
T8b949e// _destinations
T8b949e// _destination_table
T8b949e// _reverse_table
T8b949e// _announce_table
T8b949e// _held_announces
Te6edf3HEADFTb4b4b4(Te6edf3LOG_VERBOSETb4b4b4, Ta5d6ff"Ta5d6ffmem_free: %u (%u%%) [%d] flash_free: %u (%u%%) [%d] paths: %u dsts: %u revr: %u annc: %u held: %uTa5d6ff"Tb4b4b4, Te6edf3memoryTb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3memory Tff7b72/ Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff100.0Tb4b4b4)Tb4b4b4, Te6edf3memory Tff7b72- Te6edf3_last_memoryTb4b4b4, Te6edf3flashTb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3flash Tff7b72/ Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff100.0Tb4b4b4)Tb4b4b4, Te6edf3flash Tff7b72- Te6edf3_last_flashTb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_reverse_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_held_announcesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// _path_requests
T8b949e// _discovery_path_requests
T8b949e// _pending_local_path_requests
T8b949e// _discovery_pr_tags
T8b949e// _control_destinations
T8b949e// _control_hashes
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffpreqs: %u dpreqs: %u ppreqs: %u dprt: %u cdsts: %u chshs: %uTa5d6ff"Tb4b4b4, Te6edf3_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_control_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_control_hashesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// _packet_hashlist
T8b949e// _receipts
T8b949e// _link_table
T8b949e// _pending_links
T8b949e// _active_links
T8b949e// _tunnels
Tffa657uint32_t Te6edf3destination_path_responses Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destinationTb4b4b4] Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Te6edf3destination_path_responses Tff7b72+Tff7b72= Te6edf3destinationTb4b4b4.Te6edf3path_responsesTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint32_t Te6edf3interface_announces Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3interface_hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Te6edf3interface_announces Tff7b72+Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffphl: %u rcp: %u lt: %u pl: %u al: %u tun: %uTa5d6ff"Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_receiptsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_pending_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_active_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_tunnelsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffbla: %u bma: %uTa5d6ff"Tb4b4b4, Te6edf3_boundary_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_boundary_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffpin: %u pout: %u padd: %u dpr: %u ikd: %u ia: %uTffea00\rTffea00\nTa5d6ff"Tb4b4b4, Te6edf3_packets_receivedTb4b4b4, Te6edf3_packets_sentTb4b4b4, Te6edf3_destinations_addedTb4b4b4, Te6edf3destination_path_responsesTb4b4b4, Te6edf3IdentityTff7b72:Tff7b72:Te6edf3_known_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3interface_announcesTb4b4b4)Tb4b4b4;
Te6edf3_last_memory Tff7b72= Te6edf3memoryTb4b4b4;
Te6edf3_last_flash Tff7b72= Te6edf3flashTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3exit_handlerTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::exit_handler()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3persist_dataTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Te6edf3Destination Te6edf3TransportTff7b72:Tff7b72:Te6edf3find_destination_from_hashTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Searching for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Found destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3destinationTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Found destination Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3cull_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
T8b949e// TODO prune by age, or better yet by last use
T8b949e/*
std::map<Bytes, DestinationEntry>::iterator iter = _destination_table.begin();
// naively erase from front of table
std::advance(iter, _destination_table.size() - _path_table_maxsize + 1);
_destination_table.erase(_destination_table.begin(), iter);
*/
T8b949e/*
uint16_t count = 0;
std::set<DestinationEntry> sorted_values;
MapToValues(_destination_table, sorted_values);
for (auto& destination_entry : sorted_values) {
Packet announce_packet = destination_entry.announce_packet();
TRACE("Transport::cull_path_table: Removing destination " + announce_packet.destination_hash().toHex() + " from path table");
// Remove destination from path table
if (_destination_table.erase(announce_packet.destination_hash()) < 1) {
WARNING("Failed to remove destination " + announce_packet.destination_hash().toHex() + " from path table");
}
// Remove announce packet from packet table
//if (_packet_table.erase(destination_entry._announce_packet) < 1) {
// WARNING("Failed to remove packet " + destination_entry._announce_packet.toHex() + " from packet table");
//}
// Remove cached packet file
char packet_cache_path[Type::Reticulum::FILEPATH_MAXSIZE];
snprintf(packet_cache_path, Type::Reticulum::FILEPATH_MAXSIZE, "%s/%s", Reticulum::_cachepath, destination_entry._announce_packet.toHex().c_str());
if (OS::file_exists(packet_cache_path)) {
OS::remove_file(packet_cache_path);
}
++count;
if (_destination_table.size() <= _path_table_maxsize) {
break;
}
}
DEBUG("Removed " + std::to_string(count) + " path(s) from path table");
*/
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4,Te6edf3DestinationEntryTff7b72>Tff7b72> Te6edf3sorted_pairsTb4b4b4;
T8b949e// Copy key/value pairs from map into vector
Te6edf3stdTff7b72:Tff7b72:Te6edf3for_eachTb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Tff7b72const Te6edf3BytesTb4b4b4, Te6edf3DestinationEntryTff7b72>Tff7b72& Te6edf3refTb4b4b4) Tb4b4b4{
Te6edf3sorted_pairsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3refTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// Sort vector using specified comparator
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_pairsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3sorted_pairsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4,Te6edf3DestinationEntryTff7b72> Tff7b72&Te6edf3leftTb4b4b4, Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4,Te6edf3DestinationEntryTff7b72> Tff7b72&Te6edf3rightTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3leftTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestamp Tff7b72< Te6edf3rightTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestampTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// Iterate vector of sorted values
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3sorted_pairsTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table: Removing destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_packet_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_announce_packetTb4b4b4)Tb4b4b4;
Te6edf3_known_cached_packet_hashesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_announce_packetTb4b4b4)Tb4b4b4;
T8b949e// Remove destination from path table
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72< T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffFailed to remove destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Remove announce packet from packet table
T8b949e//if (_packet_table.erase(destination_entry._announce_packet) < 1) {
T8b949e// WARNING("Failed to remove packet " + destination_entry._announce_packet.toHex() + " from packet table");
T8b949e//}
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// Remove cached packet file
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3destination_entryTb4b4b4.Te6edf3_announce_packetTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3remove_fileTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3countTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff path(s) from path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_reverse_entriesTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3truncated_packet_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_reverse_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3truncated_packet_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u reverse table entriesTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_linksTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3link_id Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_link_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u linksTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_pathsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
T8b949e//_destination_table.erase(destination_hash);
Te6edf3remove_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u pathsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_discovery_path_requestsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u waiting path requestsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_tunnelsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3tunnel_id Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_tunnelsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3tunnel_idTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u tunnelsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
Served by rngit 1.4.2 - Generated in 0.43s